// SPDX-License-Identifier: GPL-2.0 /* * This file contains platform specific structure definitions * and init function used by Tiger Lake PCH. * * Copyright (c) 2022, Intel Corporation. * All Rights Reserved. * */ #include "core.h" #define ACPI_S0IX_DSM_UUID "57a6512e-3979-4e9d-9708-ff13b2508972" #define ACPI_GET_LOW_MODE_REGISTERS 1 const struct pmc_bit_map tgl_pfear_map[] = { {"PSF9", BIT(0)}, {"RES_66", BIT(1)}, {"RES_67", BIT(2)}, {"RES_68", BIT(3)}, {"RES_69", BIT(4)}, {"RES_70", BIT(5)}, {"TBTLSX", BIT(6)}, {} }; const struct pmc_bit_map *ext_tgl_pfear_map[] = { /* * Check intel_pmc_core_ids[] users of tgl_reg_map for * a list of core SoCs using this. */ cnp_pfear_map, tgl_pfear_map, NULL }; const struct pmc_bit_map tgl_clocksource_status_map[] = { {"USB2PLL_OFF_STS", BIT(18)}, {"PCIe/USB3.1_Gen2PLL_OFF_STS", BIT(19)}, {"PCIe_Gen3PLL_OFF_STS", BIT(20)}, {"OPIOPLL_OFF_STS", BIT(21)}, {"OCPLL_OFF_STS", BIT(22)}, {"MainPLL_OFF_STS", BIT(23)}, {"MIPIPLL_OFF_STS", BIT(24)}, {"Fast_XTAL_Osc_OFF_STS", BIT(25)}, {"AC_Ring_Osc_OFF_STS", BIT(26)}, {"MC_Ring_Osc_OFF_STS", BIT(27)}, {"SATAPLL_OFF_STS", BIT(29)}, {"XTAL_USB2PLL_OFF_STS", BIT(31)}, {} }; const struct pmc_bit_map tgl_power_gating_status_map[] = { {"CSME_PG_STS", BIT(0)}, {"SATA_PG_STS", BIT(1)}, {"xHCI_PG_STS", BIT(2)}, {"UFSX2_PG_STS", BIT(3)}, {"OTG_PG_STS", BIT(5)}, {"SPA_PG_STS", BIT(6)}, {"SPB_PG_STS", BIT(7)}, {"SPC_PG_STS", BIT(8)}, {"SPD_PG_STS", BIT(9)}, {"SPE_PG_STS", BIT(10)}, {"SPF_PG_STS", BIT(11)}, {"LSX_PG_STS", BIT(13)}, {"P2SB_PG_STS", BIT(14)}, {"PSF_PG_STS", BIT(15)}, {"SBR_PG_STS", BIT(16)}, {"OPIDMI_PG_STS", BIT(17)}, {"THC0_PG_STS", BIT(18)}, {"THC1_PG_STS", BIT(19)}, {"GBETSN_PG_STS", BIT(20)}, {"GBE_PG_STS", BIT(21)}, {"LPSS_PG_STS", BIT(22)}, {"MMP_UFSX2_PG_STS", BIT(23)}, {"MMP_UFSX2B_PG_STS", BIT(24)}, {"FIA_PG_STS", BIT(25)}, {} }; const struct pmc_bit_map tgl_d3_status_map[] = { {"ADSP_D3_STS", BIT(0)}, {"SATA_D3_STS", BIT(1)}, {"xHCI0_D3_STS", BIT(2)}, {"xDCI1_D3_STS", BIT(5)}, {"SDX_D3_STS", BIT(6)}, {"EMMC_D3_STS", BIT(7)}, {"IS_D3_STS", BIT(8)}, {"THC0_D3_STS", BIT(9)}, {"THC1_D3_STS", BIT(10)}, {"GBE_D3_STS", BIT(11)}, {"GBE_TSN_D3_STS", BIT(12)}, {} }; const struct pmc_bit_map tgl_vnn_req_status_map[] = { {"GPIO_COM0_VNN_REQ_STS", BIT(1)}, {"GPIO_COM1_VNN_REQ_STS", BIT(2)}, {"GPIO_COM2_VNN_REQ_STS", BIT(3)}, {"GPIO_COM3_VNN_REQ_STS", BIT(4)}, {"GPIO_COM4_VNN_REQ_STS", BIT(5)}, {"GPIO_COM5_VNN_REQ_STS", BIT(6)}, {"Audio_VNN_REQ_STS", BIT(7)}, {"ISH_VNN_REQ_STS", BIT(8)}, {"CNVI_VNN_REQ_STS", BIT(9)}, {"eSPI_VNN_REQ_STS", BIT(10)}, {"Display_VNN_REQ_STS", BIT(11)}, {"DTS_VNN_REQ_STS", BIT(12)}, {"SMBUS_VNN_REQ_STS", BIT(14)}, {"CSME_VNN_REQ_STS", BIT(15)}, {"SMLINK0_VNN_REQ_STS", BIT(16)}, {"SMLINK1_VNN_REQ_STS", BIT(17)}, {"CLINK_VNN_REQ_STS", BIT(20)}, {"DCI_VNN_REQ_STS", BIT(21)}, {"ITH_VNN_REQ_STS", BIT(22)}, {"CSME_VNN_REQ_STS", BIT(24)}, {"GBE_VNN_REQ_STS", BIT(25)}, {} }; const struct pmc_bit_map tgl_vnn_misc_status_map[] = { {"CPU_C10_REQ_STS_0", BIT(0)}, {"PCIe_LPM_En_REQ_STS_3", BIT(3)}, {"ITH_REQ_STS_5", BIT(5)}, {"CNVI_REQ_STS_6", BIT(6)}, {"ISH_REQ_STS_7", BIT(7)}, {"USB2_SUS_PG_Sys_REQ_STS_10", BIT(10)}, {"PCIe_Clk_REQ_STS_12", BIT(12)}, {"MPHY_Core_DL_REQ_STS_16", BIT(16)}, {"Break-even_En_REQ_STS_17", BIT(17)}, {"Auto-demo_En_REQ_STS_18", BIT(18)}, {"MPHY_SUS_REQ_STS_22", BIT(22)}, {"xDCI_attached_REQ_STS_24", BIT(24)}, {} }; const struct pmc_bit_map tgl_signal_status_map[] = { {"LSX_Wake0_En_STS", BIT(0)}, {"LSX_Wake0_Pol_STS", BIT(1)}, {"LSX_Wake1_En_STS", BIT(2)}, {"LSX_Wake1_Pol_STS", BIT(3)}, {"LSX_Wake2_En_STS", BIT(4)}, {"LSX_Wake2_Pol_STS", BIT(5)}, {"LSX_Wake3_En_STS", BIT(6)}, {"LSX_Wake3_Pol_STS", BIT(7)}, {"LSX_Wake4_En_STS", BIT(8)}, {"LSX_Wake4_Pol_STS", BIT(9)}, {"LSX_Wake5_En_STS", BIT(10)}, {"LSX_Wake5_Pol_STS", BIT(11)}, {"LSX_Wake6_En_STS", BIT(12)}, {"LSX_Wake6_Pol_STS", BIT(13)}, {"LSX_Wake7_En_STS", BIT(14)}, {"LSX_Wake7_Pol_STS", BIT(15)}, {"Intel_Se_IO_Wake0_En_STS", BIT(16)}, {"Intel_Se_IO_Wake0_Pol_STS", BIT(17)}, {"Intel_Se_IO_Wake1_En_STS", BIT(18)}, {"Intel_Se_IO_Wake1_Pol_STS", BIT(19)}, {"Int_Timer_SS_Wake0_En_STS", BIT(20)}, {"Int_Timer_SS_Wake0_Pol_STS", BIT(21)}, {"Int_Timer_SS_Wake1_En_STS", BIT(22)}, {"Int_Timer_SS_Wake1_Pol_STS", BIT(23)}, {"Int_Timer_SS_Wake2_En_STS", BIT(24)}, {"Int_Timer_SS_Wake2_Pol_STS", BIT(25)}, {"Int_Timer_SS_Wake3_En_STS", BIT(26)}, {"Int_Timer_SS_Wake3_Pol_STS", BIT(27)}, {"Int_Timer_SS_Wake4_En_STS", BIT(28)}, {"Int_Timer_SS_Wake4_Pol_STS", BIT(29)}, {"Int_Timer_SS_Wake5_En_STS", BIT(30)}, {"Int_Timer_SS_Wake5_Pol_STS", BIT(31)}, {} }; const struct pmc_bit_map *tgl_lpm_maps[] = { tgl_clocksource_status_map, tgl_power_gating_status_map, tgl_d3_status_map, tgl_vnn_req_status_map, tgl_vnn_misc_status_map, tgl_signal_status_map, NULL }; const struct pmc_reg_map tgl_reg_map = { .pfear_sts = ext_tgl_pfear_map, .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET, .slp_s0_res_counter_step = TGL_PMC_SLP_S0_RES_COUNTER_STEP, .ltr_show_sts = cnp_ltr_show_map, .msr_sts = msr_map, .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET, .regmap_length = CNP_PMC_MMIO_REG_LEN, .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A, .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES, .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, .ltr_ignore_max = TGL_NUM_IP_IGN_ALLOWED, .lpm_num_maps = TGL_LPM_NUM_MAPS, .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2, .lpm_sts_latch_en_offset = TGL_LPM_STS_LATCH_EN_OFFSET, .lpm_en_offset = TGL_LPM_EN_OFFSET, .lpm_priority_offset = TGL_LPM_PRI_OFFSET, .lpm_residency_offset = TGL_LPM_RESIDENCY_OFFSET, .lpm_sts = tgl_lpm_maps, .lpm_status_offset = TGL_LPM_STATUS_OFFSET, .lpm_live_status_offset = TGL_LPM_LIVE_STATUS_OFFSET, .etr3_offset = ETR3_OFFSET, }; void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev) { struct pmc_dev *pmcdev = platform_get_drvdata(pdev); struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; const int num_maps = pmc->map->lpm_num_maps; u32 lpm_size = LPM_MAX_NUM_MODES * num_maps * 4; union acpi_object *out_obj; struct acpi_device *adev; guid_t s0ix_dsm_guid; u32 *lpm_req_regs, *addr; adev = ACPI_COMPANION(&pdev->dev); if (!adev) return; guid_parse(ACPI_S0IX_DSM_UUID, &s0ix_dsm_guid); out_obj = acpi_evaluate_dsm_typed(adev->handle, &s0ix_dsm_guid, 0, ACPI_GET_LOW_MODE_REGISTERS, NULL, ACPI_TYPE_BUFFER); if (out_obj) { u32 size = out_obj->buffer.length; if (size != lpm_size) { acpi_handle_debug(adev->handle, "_DSM returned unexpected buffer size, have %u, expect %u\n", size, lpm_size); goto free_acpi_obj; } } else { acpi_handle_debug(adev->handle, "_DSM function 0 evaluation failed\n"); goto free_acpi_obj; } addr = (u32 *)out_obj->buffer.pointer; lpm_req_regs = devm_kzalloc(&pdev->dev, lpm_size * sizeof(u32), GFP_KERNEL); if (!lpm_req_regs) goto free_acpi_obj; memcpy(lpm_req_regs, addr, lpm_size); pmc->lpm_req_regs = lpm_req_regs; free_acpi_obj: ACPI_FREE(out_obj); } int tgl_core_init(struct pmc_dev *pmcdev) { struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; int ret; pmc->map = &tgl_reg_map; ret = get_primary_reg_base(pmc); if (ret) return ret; pmc_core_get_tgl_lpm_reqs(pmcdev->pdev); /* Due to a hardware limitation, the GBE LTR blocks PC10 * when a cable is attached. Tell the PMC to ignore it. */ dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n"); pmc_core_send_ltr_ignore(pmcdev, 3); return 0; }