From 2b6cb8f2e88b416393d2b34cad51bfe6e1aae8a7 Mon Sep 17 00:00:00 2001 From: Kate Hsuan Date: Fri, 20 Aug 2021 14:04:46 +0300 Subject: platform/x86: intel_telemetry: Move to intel sub-directory Move Intel telemetry driver to intel sub-directory to improve readability. While at it, spell APL fully in the Kconfig. Signed-off-by: Kate Hsuan Reviewed-by: Hans de Goede Signed-off-by: Andy Shevchenko Reviewed-by: Rajneesh Bhardwaj Link: https://lore.kernel.org/r/20210820110458.73018-9-andriy.shevchenko@linux.intel.com Signed-off-by: Hans de Goede --- drivers/platform/x86/intel_telemetry_pltdrv.c | 1189 ------------------------- 1 file changed, 1189 deletions(-) delete mode 100644 drivers/platform/x86/intel_telemetry_pltdrv.c (limited to 'drivers/platform/x86/intel_telemetry_pltdrv.c') diff --git a/drivers/platform/x86/intel_telemetry_pltdrv.c b/drivers/platform/x86/intel_telemetry_pltdrv.c deleted file mode 100644 index 405dea87de6b..000000000000 --- a/drivers/platform/x86/intel_telemetry_pltdrv.c +++ /dev/null @@ -1,1189 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Intel SOC Telemetry Platform Driver: Currently supports APL - * Copyright (c) 2015, Intel Corporation. - * All Rights Reserved. - * - * This file provides the platform specific telemetry implementation for APL. - * It used the PUNIT and PMC IPC interfaces for configuring the counters. - * The accumulated results are fetched from SRAM. - */ - -#include -#include -#include - -#include -#include -#include -#include - -#define DRIVER_NAME "intel_telemetry" -#define DRIVER_VERSION "1.0.0" - -#define TELEM_TRC_VERBOSITY_MASK 0x3 - -#define TELEM_MIN_PERIOD(x) ((x) & 0x7F0000) -#define TELEM_MAX_PERIOD(x) ((x) & 0x7F000000) -#define TELEM_SAMPLE_PERIOD_INVALID(x) ((x) & (BIT(7))) -#define TELEM_CLEAR_SAMPLE_PERIOD(x) ((x) &= ~0x7F) - -#define TELEM_SAMPLING_DEFAULT_PERIOD 0xD - -#define TELEM_MAX_EVENTS_SRAM 28 -#define TELEM_SSRAM_STARTTIME_OFFSET 8 -#define TELEM_SSRAM_EVTLOG_OFFSET 16 - -#define IOSS_TELEM 0xeb -#define IOSS_TELEM_EVENT_READ 0x0 -#define IOSS_TELEM_EVENT_WRITE 0x1 -#define IOSS_TELEM_INFO_READ 0x2 -#define IOSS_TELEM_TRACE_CTL_READ 0x5 -#define IOSS_TELEM_TRACE_CTL_WRITE 0x6 -#define IOSS_TELEM_EVENT_CTL_READ 0x7 -#define IOSS_TELEM_EVENT_CTL_WRITE 0x8 -#define IOSS_TELEM_EVT_WRITE_SIZE 0x3 - -#define TELEM_INFO_SRAMEVTS_MASK 0xFF00 -#define TELEM_INFO_SRAMEVTS_SHIFT 0x8 -#define TELEM_SSRAM_READ_TIMEOUT 10 - -#define TELEM_INFO_NENABLES_MASK 0xFF -#define TELEM_EVENT_ENABLE 0x8000 - -#define TELEM_MASK_BIT 1 -#define TELEM_MASK_BYTE 0xFF -#define BYTES_PER_LONG 8 -#define TELEM_MASK_PCS_STATE 0xF - -#define TELEM_DISABLE(x) ((x) &= ~(BIT(31))) -#define TELEM_CLEAR_EVENTS(x) ((x) |= (BIT(30))) -#define TELEM_ENABLE_SRAM_EVT_TRACE(x) ((x) &= ~(BIT(30) | BIT(24))) -#define TELEM_ENABLE_PERIODIC(x) ((x) |= (BIT(23) | BIT(31) | BIT(7))) -#define TELEM_EXTRACT_VERBOSITY(x, y) ((y) = (((x) >> 27) & 0x3)) -#define TELEM_CLEAR_VERBOSITY_BITS(x) ((x) &= ~(BIT(27) | BIT(28))) -#define TELEM_SET_VERBOSITY_BITS(x, y) ((x) |= ((y) << 27)) - -enum telemetry_action { - TELEM_UPDATE = 0, - TELEM_ADD, - TELEM_RESET, - TELEM_ACTION_NONE -}; - -struct telem_ssram_region { - u64 timestamp; - u64 start_time; - u64 events[TELEM_MAX_EVENTS_SRAM]; -}; - -static struct telemetry_plt_config *telm_conf; - -/* - * The following counters are programmed by default during setup. - * Only 20 allocated to kernel driver - */ -static struct telemetry_evtmap - telemetry_apl_ioss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = { - {"SOC_S0IX_TOTAL_RES", 0x4800}, - {"SOC_S0IX_TOTAL_OCC", 0x4000}, - {"SOC_S0IX_SHALLOW_RES", 0x4801}, - {"SOC_S0IX_SHALLOW_OCC", 0x4001}, - {"SOC_S0IX_DEEP_RES", 0x4802}, - {"SOC_S0IX_DEEP_OCC", 0x4002}, - {"PMC_POWER_GATE", 0x5818}, - {"PMC_D3_STATES", 0x5819}, - {"PMC_D0I3_STATES", 0x581A}, - {"PMC_S0IX_WAKE_REASON_GPIO", 0x6000}, - {"PMC_S0IX_WAKE_REASON_TIMER", 0x6001}, - {"PMC_S0IX_WAKE_REASON_VNNREQ", 0x6002}, - {"PMC_S0IX_WAKE_REASON_LOWPOWER", 0x6003}, - {"PMC_S0IX_WAKE_REASON_EXTERNAL", 0x6004}, - {"PMC_S0IX_WAKE_REASON_MISC", 0x6005}, - {"PMC_S0IX_BLOCKING_IPS_D3_D0I3", 0x6006}, - {"PMC_S0IX_BLOCKING_IPS_PG", 0x6007}, - {"PMC_S0IX_BLOCKING_MISC_IPS_PG", 0x6008}, - {"PMC_S0IX_BLOCK_IPS_VNN_REQ", 0x6009}, - {"PMC_S0IX_BLOCK_IPS_CLOCKS", 0x600B}, -}; - - -static struct telemetry_evtmap - telemetry_apl_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = { - {"IA_CORE0_C6_RES", 0x0400}, - {"IA_CORE0_C6_CTR", 0x0000}, - {"IA_MODULE0_C7_RES", 0x0410}, - {"IA_MODULE0_C7_CTR", 0x000E}, - {"IA_C0_RES", 0x0805}, - {"PCS_LTR", 0x2801}, - {"PSTATES", 0x2802}, - {"SOC_S0I3_RES", 0x0409}, - {"SOC_S0I3_CTR", 0x000A}, - {"PCS_S0I3_CTR", 0x0009}, - {"PCS_C1E_RES", 0x041A}, - {"PCS_IDLE_STATUS", 0x2806}, - {"IA_PERF_LIMITS", 0x280B}, - {"GT_PERF_LIMITS", 0x280C}, - {"PCS_WAKEUP_S0IX_CTR", 0x0030}, - {"PCS_IDLE_BLOCKED", 0x2C00}, - {"PCS_S0IX_BLOCKED", 0x2C01}, - {"PCS_S0IX_WAKE_REASONS", 0x2C02}, - {"PCS_LTR_BLOCKING", 0x2C03}, - {"PC2_AND_MEM_SHALLOW_IDLE_RES", 0x1D40}, -}; - -static struct telemetry_evtmap - telemetry_glk_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = { - {"IA_CORE0_C6_RES", 0x0400}, - {"IA_CORE0_C6_CTR", 0x0000}, - {"IA_MODULE0_C7_RES", 0x0410}, - {"IA_MODULE0_C7_CTR", 0x000C}, - {"IA_C0_RES", 0x0805}, - {"PCS_LTR", 0x2801}, - {"PSTATES", 0x2802}, - {"SOC_S0I3_RES", 0x0407}, - {"SOC_S0I3_CTR", 0x0008}, - {"PCS_S0I3_CTR", 0x0007}, - {"PCS_C1E_RES", 0x0414}, - {"PCS_IDLE_STATUS", 0x2806}, - {"IA_PERF_LIMITS", 0x280B}, - {"GT_PERF_LIMITS", 0x280C}, - {"PCS_WAKEUP_S0IX_CTR", 0x0025}, - {"PCS_IDLE_BLOCKED", 0x2C00}, - {"PCS_S0IX_BLOCKED", 0x2C01}, - {"PCS_S0IX_WAKE_REASONS", 0x2C02}, - {"PCS_LTR_BLOCKING", 0x2C03}, - {"PC2_AND_MEM_SHALLOW_IDLE_RES", 0x1D40}, -}; - -/* APL specific Data */ -static struct telemetry_plt_config telem_apl_config = { - .pss_config = { - .telem_evts = telemetry_apl_pss_default_events, - }, - .ioss_config = { - .telem_evts = telemetry_apl_ioss_default_events, - }, -}; - -/* GLK specific Data */ -static struct telemetry_plt_config telem_glk_config = { - .pss_config = { - .telem_evts = telemetry_glk_pss_default_events, - }, - .ioss_config = { - .telem_evts = telemetry_apl_ioss_default_events, - }, -}; - -static const struct x86_cpu_id telemetry_cpu_ids[] = { - X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &telem_apl_config), - X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS, &telem_glk_config), - {} -}; - -MODULE_DEVICE_TABLE(x86cpu, telemetry_cpu_ids); - -static inline int telem_get_unitconfig(enum telemetry_unit telem_unit, - struct telemetry_unit_config **unit_config) -{ - if (telem_unit == TELEM_PSS) - *unit_config = &(telm_conf->pss_config); - else if (telem_unit == TELEM_IOSS) - *unit_config = &(telm_conf->ioss_config); - else - return -EINVAL; - - return 0; - -} - -static int telemetry_check_evtid(enum telemetry_unit telem_unit, - u32 *evtmap, u8 len, - enum telemetry_action action) -{ - struct telemetry_unit_config *unit_config; - int ret; - - ret = telem_get_unitconfig(telem_unit, &unit_config); - if (ret < 0) - return ret; - - switch (action) { - case TELEM_RESET: - if (len > TELEM_MAX_EVENTS_SRAM) - return -EINVAL; - - break; - - case TELEM_UPDATE: - if (len > TELEM_MAX_EVENTS_SRAM) - return -EINVAL; - - if ((len > 0) && (evtmap == NULL)) - return -EINVAL; - - break; - - case TELEM_ADD: - if ((len + unit_config->ssram_evts_used) > - TELEM_MAX_EVENTS_SRAM) - return -EINVAL; - - if ((len > 0) && (evtmap == NULL)) - return -EINVAL; - - break; - - default: - pr_err("Unknown Telemetry action specified %d\n", action); - return -EINVAL; - } - - return 0; -} - - -static inline int telemetry_plt_config_ioss_event(u32 evt_id, int index) -{ - u32 write_buf; - - write_buf = evt_id | TELEM_EVENT_ENABLE; - write_buf <<= BITS_PER_BYTE; - write_buf |= index; - - return intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM, - IOSS_TELEM_EVENT_WRITE, &write_buf, - IOSS_TELEM_EVT_WRITE_SIZE, NULL, 0); -} - -static inline int telemetry_plt_config_pss_event(u32 evt_id, int index) -{ - u32 write_buf; - int ret; - - write_buf = evt_id | TELEM_EVENT_ENABLE; - ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT, - index, 0, &write_buf, NULL); - - return ret; -} - -static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig, - enum telemetry_action action) -{ - struct intel_scu_ipc_dev *scu = telm_conf->scu; - u8 num_ioss_evts, ioss_period; - int ret, index, idx; - u32 *ioss_evtmap; - u32 telem_ctrl; - - num_ioss_evts = evtconfig.num_evts; - ioss_period = evtconfig.period; - ioss_evtmap = evtconfig.evtmap; - - /* Get telemetry EVENT CTL */ - ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, - IOSS_TELEM_EVENT_CTL_READ, NULL, 0, - &telem_ctrl, sizeof(telem_ctrl)); - if (ret) { - pr_err("IOSS TELEM_CTRL Read Failed\n"); - return ret; - } - - /* Disable Telemetry */ - TELEM_DISABLE(telem_ctrl); - - ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, - IOSS_TELEM_EVENT_CTL_WRITE, &telem_ctrl, - sizeof(telem_ctrl), NULL, 0); - if (ret) { - pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n"); - return ret; - } - - - /* Reset Everything */ - if (action == TELEM_RESET) { - /* Clear All Events */ - TELEM_CLEAR_EVENTS(telem_ctrl); - - ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, - IOSS_TELEM_EVENT_CTL_WRITE, - &telem_ctrl, sizeof(telem_ctrl), - NULL, 0); - if (ret) { - pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n"); - return ret; - } - telm_conf->ioss_config.ssram_evts_used = 0; - - /* Configure Events */ - for (idx = 0; idx < num_ioss_evts; idx++) { - if (telemetry_plt_config_ioss_event( - telm_conf->ioss_config.telem_evts[idx].evt_id, - idx)) { - pr_err("IOSS TELEM_RESET Fail for data: %x\n", - telm_conf->ioss_config.telem_evts[idx].evt_id); - continue; - } - telm_conf->ioss_config.ssram_evts_used++; - } - } - - /* Re-Configure Everything */ - if (action == TELEM_UPDATE) { - /* Clear All Events */ - TELEM_CLEAR_EVENTS(telem_ctrl); - - ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, - IOSS_TELEM_EVENT_CTL_WRITE, - &telem_ctrl, sizeof(telem_ctrl), - NULL, 0); - if (ret) { - pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n"); - return ret; - } - telm_conf->ioss_config.ssram_evts_used = 0; - - /* Configure Events */ - for (index = 0; index < num_ioss_evts; index++) { - telm_conf->ioss_config.telem_evts[index].evt_id = - ioss_evtmap[index]; - - if (telemetry_plt_config_ioss_event( - telm_conf->ioss_config.telem_evts[index].evt_id, - index)) { - pr_err("IOSS TELEM_UPDATE Fail for Evt%x\n", - ioss_evtmap[index]); - continue; - } - telm_conf->ioss_config.ssram_evts_used++; - } - } - - /* Add some Events */ - if (action == TELEM_ADD) { - /* Configure Events */ - for (index = telm_conf->ioss_config.ssram_evts_used, idx = 0; - idx < num_ioss_evts; index++, idx++) { - telm_conf->ioss_config.telem_evts[index].evt_id = - ioss_evtmap[idx]; - - if (telemetry_plt_config_ioss_event( - telm_conf->ioss_config.telem_evts[index].evt_id, - index)) { - pr_err("IOSS TELEM_ADD Fail for Event %x\n", - ioss_evtmap[idx]); - continue; - } - telm_conf->ioss_config.ssram_evts_used++; - } - } - - /* Enable Periodic Telemetry Events and enable SRAM trace */ - TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl); - TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl); - TELEM_ENABLE_PERIODIC(telem_ctrl); - telem_ctrl |= ioss_period; - - ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, - IOSS_TELEM_EVENT_CTL_WRITE, - &telem_ctrl, sizeof(telem_ctrl), NULL, 0); - if (ret) { - pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n"); - return ret; - } - - telm_conf->ioss_config.curr_period = ioss_period; - - return 0; -} - - -static int telemetry_setup_pssevtconfig(struct telemetry_evtconfig evtconfig, - enum telemetry_action action) -{ - u8 num_pss_evts, pss_period; - int ret, index, idx; - u32 *pss_evtmap; - u32 telem_ctrl; - - num_pss_evts = evtconfig.num_evts; - pss_period = evtconfig.period; - pss_evtmap = evtconfig.evtmap; - - /* PSS Config */ - /* Get telemetry EVENT CTL */ - ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL, - 0, 0, NULL, &telem_ctrl); - if (ret) { - pr_err("PSS TELEM_CTRL Read Failed\n"); - return ret; - } - - /* Disable Telemetry */ - TELEM_DISABLE(telem_ctrl); - ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL, - 0, 0, &telem_ctrl, NULL); - if (ret) { - pr_err("PSS TELEM_CTRL Event Disable Write Failed\n"); - return ret; - } - - /* Reset Everything */ - if (action == TELEM_RESET) { - /* Clear All Events */ - TELEM_CLEAR_EVENTS(telem_ctrl); - - ret = intel_punit_ipc_command( - IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL, - 0, 0, &telem_ctrl, NULL); - if (ret) { - pr_err("PSS TELEM_CTRL Event Disable Write Failed\n"); - return ret; - } - telm_conf->pss_config.ssram_evts_used = 0; - /* Configure Events */ - for (idx = 0; idx < num_pss_evts; idx++) { - if (telemetry_plt_config_pss_event( - telm_conf->pss_config.telem_evts[idx].evt_id, - idx)) { - pr_err("PSS TELEM_RESET Fail for Event %x\n", - telm_conf->pss_config.telem_evts[idx].evt_id); - continue; - } - telm_conf->pss_config.ssram_evts_used++; - } - } - - /* Re-Configure Everything */ - if (action == TELEM_UPDATE) { - /* Clear All Events */ - TELEM_CLEAR_EVENTS(telem_ctrl); - - ret = intel_punit_ipc_command( - IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL, - 0, 0, &telem_ctrl, NULL); - if (ret) { - pr_err("PSS TELEM_CTRL Event Disable Write Failed\n"); - return ret; - } - telm_conf->pss_config.ssram_evts_used = 0; - - /* Configure Events */ - for (index = 0; index < num_pss_evts; index++) { - telm_conf->pss_config.telem_evts[index].evt_id = - pss_evtmap[index]; - - if (telemetry_plt_config_pss_event( - telm_conf->pss_config.telem_evts[index].evt_id, - index)) { - pr_err("PSS TELEM_UPDATE Fail for Event %x\n", - pss_evtmap[index]); - continue; - } - telm_conf->pss_config.ssram_evts_used++; - } - } - - /* Add some Events */ - if (action == TELEM_ADD) { - /* Configure Events */ - for (index = telm_conf->pss_config.ssram_evts_used, idx = 0; - idx < num_pss_evts; index++, idx++) { - - telm_conf->pss_config.telem_evts[index].evt_id = - pss_evtmap[idx]; - - if (telemetry_plt_config_pss_event( - telm_conf->pss_config.telem_evts[index].evt_id, - index)) { - pr_err("PSS TELEM_ADD Fail for Event %x\n", - pss_evtmap[idx]); - continue; - } - telm_conf->pss_config.ssram_evts_used++; - } - } - - /* Enable Periodic Telemetry Events and enable SRAM trace */ - TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl); - TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl); - TELEM_ENABLE_PERIODIC(telem_ctrl); - telem_ctrl |= pss_period; - - ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL, - 0, 0, &telem_ctrl, NULL); - if (ret) { - pr_err("PSS TELEM_CTRL Event Enable Write Failed\n"); - return ret; - } - - telm_conf->pss_config.curr_period = pss_period; - - return 0; -} - -static int telemetry_setup_evtconfig(struct telemetry_evtconfig pss_evtconfig, - struct telemetry_evtconfig ioss_evtconfig, - enum telemetry_action action) -{ - int ret; - - mutex_lock(&(telm_conf->telem_lock)); - - if ((action == TELEM_UPDATE) && (telm_conf->telem_in_use)) { - ret = -EBUSY; - goto out; - } - - ret = telemetry_check_evtid(TELEM_PSS, pss_evtconfig.evtmap, - pss_evtconfig.num_evts, action); - if (ret) - goto out; - - ret = telemetry_check_evtid(TELEM_IOSS, ioss_evtconfig.evtmap, - ioss_evtconfig.num_evts, action); - if (ret) - goto out; - - if (ioss_evtconfig.num_evts) { - ret = telemetry_setup_iossevtconfig(ioss_evtconfig, action); - if (ret) - goto out; - } - - if (pss_evtconfig.num_evts) { - ret = telemetry_setup_pssevtconfig(pss_evtconfig, action); - if (ret) - goto out; - } - - if ((action == TELEM_UPDATE) || (action == TELEM_ADD)) - telm_conf->telem_in_use = true; - else - telm_conf->telem_in_use = false; - -out: - mutex_unlock(&(telm_conf->telem_lock)); - return ret; -} - -static int telemetry_setup(struct platform_device *pdev) -{ - struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig; - u32 read_buf, events, event_regs; - int ret; - - ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM, - IOSS_TELEM_INFO_READ, NULL, 0, - &read_buf, sizeof(read_buf)); - if (ret) { - dev_err(&pdev->dev, "IOSS TELEM_INFO Read Failed\n"); - return ret; - } - - /* Get telemetry Info */ - events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >> - TELEM_INFO_SRAMEVTS_SHIFT; - event_regs = read_buf & TELEM_INFO_NENABLES_MASK; - if ((events < TELEM_MAX_EVENTS_SRAM) || - (event_regs < TELEM_MAX_EVENTS_SRAM)) { - dev_err(&pdev->dev, "IOSS:Insufficient Space for SRAM Trace\n"); - dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n", - events, event_regs); - return -ENOMEM; - } - - telm_conf->ioss_config.min_period = TELEM_MIN_PERIOD(read_buf); - telm_conf->ioss_config.max_period = TELEM_MAX_PERIOD(read_buf); - - /* PUNIT Mailbox Setup */ - ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_INFO, 0, 0, - NULL, &read_buf); - if (ret) { - dev_err(&pdev->dev, "PSS TELEM_INFO Read Failed\n"); - return ret; - } - - /* Get telemetry Info */ - events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >> - TELEM_INFO_SRAMEVTS_SHIFT; - event_regs = read_buf & TELEM_INFO_SRAMEVTS_MASK; - if ((events < TELEM_MAX_EVENTS_SRAM) || - (event_regs < TELEM_MAX_EVENTS_SRAM)) { - dev_err(&pdev->dev, "PSS:Insufficient Space for SRAM Trace\n"); - dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n", - events, event_regs); - return -ENOMEM; - } - - telm_conf->pss_config.min_period = TELEM_MIN_PERIOD(read_buf); - telm_conf->pss_config.max_period = TELEM_MAX_PERIOD(read_buf); - - pss_evtconfig.evtmap = NULL; - pss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS; - pss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD; - - ioss_evtconfig.evtmap = NULL; - ioss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS; - ioss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD; - - ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig, - TELEM_RESET); - if (ret) { - dev_err(&pdev->dev, "TELEMETRY Setup Failed\n"); - return ret; - } - return 0; -} - -static int telemetry_plt_update_events(struct telemetry_evtconfig pss_evtconfig, - struct telemetry_evtconfig ioss_evtconfig) -{ - int ret; - - if ((pss_evtconfig.num_evts > 0) && - (TELEM_SAMPLE_PERIOD_INVALID(pss_evtconfig.period))) { - pr_err("PSS Sampling Period Out of Range\n"); - return -EINVAL; - } - - if ((ioss_evtconfig.num_evts > 0) && - (TELEM_SAMPLE_PERIOD_INVALID(ioss_evtconfig.period))) { - pr_err("IOSS Sampling Period Out of Range\n"); - return -EINVAL; - } - - ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig, - TELEM_UPDATE); - if (ret) - pr_err("TELEMETRY Config Failed\n"); - - return ret; -} - - -static int telemetry_plt_set_sampling_period(u8 pss_period, u8 ioss_period) -{ - u32 telem_ctrl = 0; - int ret = 0; - - mutex_lock(&(telm_conf->telem_lock)); - if (ioss_period) { - struct intel_scu_ipc_dev *scu = telm_conf->scu; - - if (TELEM_SAMPLE_PERIOD_INVALID(ioss_period)) { - pr_err("IOSS Sampling Period Out of Range\n"); - ret = -EINVAL; - goto out; - } - - /* Get telemetry EVENT CTL */ - ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, - IOSS_TELEM_EVENT_CTL_READ, NULL, 0, - &telem_ctrl, sizeof(telem_ctrl)); - if (ret) { - pr_err("IOSS TELEM_CTRL Read Failed\n"); - goto out; - } - - /* Disable Telemetry */ - TELEM_DISABLE(telem_ctrl); - - ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, - IOSS_TELEM_EVENT_CTL_WRITE, - &telem_ctrl, sizeof(telem_ctrl), - NULL, 0); - if (ret) { - pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n"); - goto out; - } - - /* Enable Periodic Telemetry Events and enable SRAM trace */ - TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl); - TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl); - TELEM_ENABLE_PERIODIC(telem_ctrl); - telem_ctrl |= ioss_period; - - ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, - IOSS_TELEM_EVENT_CTL_WRITE, - &telem_ctrl, sizeof(telem_ctrl), - NULL, 0); - if (ret) { - pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n"); - goto out; - } - telm_conf->ioss_config.curr_period = ioss_period; - } - - if (pss_period) { - if (TELEM_SAMPLE_PERIOD_INVALID(pss_period)) { - pr_err("PSS Sampling Period Out of Range\n"); - ret = -EINVAL; - goto out; - } - - /* Get telemetry EVENT CTL */ - ret = intel_punit_ipc_command( - IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL, - 0, 0, NULL, &telem_ctrl); - if (ret) { - pr_err("PSS TELEM_CTRL Read Failed\n"); - goto out; - } - - /* Disable Telemetry */ - TELEM_DISABLE(telem_ctrl); - ret = intel_punit_ipc_command( - IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL, - 0, 0, &telem_ctrl, NULL); - if (ret) { - pr_err("PSS TELEM_CTRL Event Disable Write Failed\n"); - goto out; - } - - /* Enable Periodic Telemetry Events and enable SRAM trace */ - TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl); - TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl); - TELEM_ENABLE_PERIODIC(telem_ctrl); - telem_ctrl |= pss_period; - - ret = intel_punit_ipc_command( - IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL, - 0, 0, &telem_ctrl, NULL); - if (ret) { - pr_err("PSS TELEM_CTRL Event Enable Write Failed\n"); - goto out; - } - telm_conf->pss_config.curr_period = pss_period; - } - -out: - mutex_unlock(&(telm_conf->telem_lock)); - return ret; -} - - -static int telemetry_plt_get_sampling_period(u8 *pss_min_period, - u8 *pss_max_period, - u8 *ioss_min_period, - u8 *ioss_max_period) -{ - *pss_min_period = telm_conf->pss_config.min_period; - *pss_max_period = telm_conf->pss_config.max_period; - *ioss_min_period = telm_conf->ioss_config.min_period; - *ioss_max_period = telm_conf->ioss_config.max_period; - - return 0; -} - - -static int telemetry_plt_reset_events(void) -{ - struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig; - int ret; - - pss_evtconfig.evtmap = NULL; - pss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS; - pss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD; - - ioss_evtconfig.evtmap = NULL; - ioss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS; - ioss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD; - - ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig, - TELEM_RESET); - if (ret) - pr_err("TELEMETRY Reset Failed\n"); - - return ret; -} - - -static int telemetry_plt_get_eventconfig(struct telemetry_evtconfig *pss_config, - struct telemetry_evtconfig *ioss_config, - int pss_len, int ioss_len) -{ - u32 *pss_evtmap, *ioss_evtmap; - u32 index; - - pss_evtmap = pss_config->evtmap; - ioss_evtmap = ioss_config->evtmap; - - mutex_lock(&(telm_conf->telem_lock)); - pss_config->num_evts = telm_conf->pss_config.ssram_evts_used; - ioss_config->num_evts = telm_conf->ioss_config.ssram_evts_used; - - pss_config->period = telm_conf->pss_config.curr_period; - ioss_config->period = telm_conf->ioss_config.curr_period; - - if ((pss_len < telm_conf->pss_config.ssram_evts_used) || - (ioss_len < telm_conf->ioss_config.ssram_evts_used)) { - mutex_unlock(&(telm_conf->telem_lock)); - return -EINVAL; - } - - for (index = 0; index < telm_conf->pss_config.ssram_evts_used; - index++) { - pss_evtmap[index] = - telm_conf->pss_config.telem_evts[index].evt_id; - } - - for (index = 0; index < telm_conf->ioss_config.ssram_evts_used; - index++) { - ioss_evtmap[index] = - telm_conf->ioss_config.telem_evts[index].evt_id; - } - - mutex_unlock(&(telm_conf->telem_lock)); - return 0; -} - - -static int telemetry_plt_add_events(u8 num_pss_evts, u8 num_ioss_evts, - u32 *pss_evtmap, u32 *ioss_evtmap) -{ - struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig; - int ret; - - pss_evtconfig.evtmap = pss_evtmap; - pss_evtconfig.num_evts = num_pss_evts; - pss_evtconfig.period = telm_conf->pss_config.curr_period; - - ioss_evtconfig.evtmap = ioss_evtmap; - ioss_evtconfig.num_evts = num_ioss_evts; - ioss_evtconfig.period = telm_conf->ioss_config.curr_period; - - ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig, - TELEM_ADD); - if (ret) - pr_err("TELEMETRY ADD Failed\n"); - - return ret; -} - -static int telem_evtlog_read(enum telemetry_unit telem_unit, - struct telem_ssram_region *ssram_region, u8 len) -{ - struct telemetry_unit_config *unit_config; - u64 timestamp_prev, timestamp_next; - int ret, index, timeout = 0; - - ret = telem_get_unitconfig(telem_unit, &unit_config); - if (ret < 0) - return ret; - - if (len > unit_config->ssram_evts_used) - len = unit_config->ssram_evts_used; - - do { - timestamp_prev = readq(unit_config->regmap); - if (!timestamp_prev) { - pr_err("Ssram under update. Please Try Later\n"); - return -EBUSY; - } - - ssram_region->start_time = readq(unit_config->regmap + - TELEM_SSRAM_STARTTIME_OFFSET); - - for (index = 0; index < len; index++) { - ssram_region->events[index] = - readq(unit_config->regmap + TELEM_SSRAM_EVTLOG_OFFSET + - BYTES_PER_LONG*index); - } - - timestamp_next = readq(unit_config->regmap); - if (!timestamp_next) { - pr_err("Ssram under update. Please Try Later\n"); - return -EBUSY; - } - - if (timeout++ > TELEM_SSRAM_READ_TIMEOUT) { - pr_err("Timeout while reading Events\n"); - return -EBUSY; - } - - } while (timestamp_prev != timestamp_next); - - ssram_region->timestamp = timestamp_next; - - return len; -} - -static int telemetry_plt_raw_read_eventlog(enum telemetry_unit telem_unit, - struct telemetry_evtlog *evtlog, - int len, int log_all_evts) -{ - int index, idx1, ret, readlen = len; - struct telem_ssram_region ssram_region; - struct telemetry_evtmap *evtmap; - - switch (telem_unit) { - case TELEM_PSS: - evtmap = telm_conf->pss_config.telem_evts; - break; - - case TELEM_IOSS: - evtmap = telm_conf->ioss_config.telem_evts; - break; - - default: - pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit); - return -EINVAL; - } - - if (!log_all_evts) - readlen = TELEM_MAX_EVENTS_SRAM; - - ret = telem_evtlog_read(telem_unit, &ssram_region, readlen); - if (ret < 0) - return ret; - - /* Invalid evt-id array specified via length mismatch */ - if ((!log_all_evts) && (len > ret)) - return -EINVAL; - - if (log_all_evts) - for (index = 0; index < ret; index++) { - evtlog[index].telem_evtlog = ssram_region.events[index]; - evtlog[index].telem_evtid = evtmap[index].evt_id; - } - else - for (index = 0, readlen = 0; (index < ret) && (readlen < len); - index++) { - for (idx1 = 0; idx1 < len; idx1++) { - /* Elements matched */ - if (evtmap[index].evt_id == - evtlog[idx1].telem_evtid) { - evtlog[idx1].telem_evtlog = - ssram_region.events[index]; - readlen++; - - break; - } - } - } - - return readlen; -} - -static int telemetry_plt_read_eventlog(enum telemetry_unit telem_unit, - struct telemetry_evtlog *evtlog, int len, int log_all_evts) -{ - int ret; - - mutex_lock(&(telm_conf->telem_lock)); - ret = telemetry_plt_raw_read_eventlog(telem_unit, evtlog, - len, log_all_evts); - mutex_unlock(&(telm_conf->telem_lock)); - - return ret; -} - -static int telemetry_plt_get_trace_verbosity(enum telemetry_unit telem_unit, - u32 *verbosity) -{ - u32 temp = 0; - int ret; - - if (verbosity == NULL) - return -EINVAL; - - mutex_lock(&(telm_conf->telem_trace_lock)); - switch (telem_unit) { - case TELEM_PSS: - ret = intel_punit_ipc_command( - IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL, - 0, 0, NULL, &temp); - if (ret) { - pr_err("PSS TRACE_CTRL Read Failed\n"); - goto out; - } - - break; - - case TELEM_IOSS: - ret = intel_scu_ipc_dev_command(telm_conf->scu, - IOSS_TELEM, IOSS_TELEM_TRACE_CTL_READ, - NULL, 0, &temp, sizeof(temp)); - if (ret) { - pr_err("IOSS TRACE_CTL Read Failed\n"); - goto out; - } - - break; - - default: - pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit); - ret = -EINVAL; - break; - } - TELEM_EXTRACT_VERBOSITY(temp, *verbosity); - -out: - mutex_unlock(&(telm_conf->telem_trace_lock)); - return ret; -} - -static int telemetry_plt_set_trace_verbosity(enum telemetry_unit telem_unit, - u32 verbosity) -{ - u32 temp = 0; - int ret; - - verbosity &= TELEM_TRC_VERBOSITY_MASK; - - mutex_lock(&(telm_conf->telem_trace_lock)); - switch (telem_unit) { - case TELEM_PSS: - ret = intel_punit_ipc_command( - IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL, - 0, 0, NULL, &temp); - if (ret) { - pr_err("PSS TRACE_CTRL Read Failed\n"); - goto out; - } - - TELEM_CLEAR_VERBOSITY_BITS(temp); - TELEM_SET_VERBOSITY_BITS(temp, verbosity); - - ret = intel_punit_ipc_command( - IPC_PUNIT_BIOS_WRITE_TELE_TRACE_CTRL, - 0, 0, &temp, NULL); - if (ret) { - pr_err("PSS TRACE_CTRL Verbosity Set Failed\n"); - goto out; - } - break; - - case TELEM_IOSS: - ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM, - IOSS_TELEM_TRACE_CTL_READ, - NULL, 0, &temp, sizeof(temp)); - if (ret) { - pr_err("IOSS TRACE_CTL Read Failed\n"); - goto out; - } - - TELEM_CLEAR_VERBOSITY_BITS(temp); - TELEM_SET_VERBOSITY_BITS(temp, verbosity); - - ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM, - IOSS_TELEM_TRACE_CTL_WRITE, - &temp, sizeof(temp), NULL, 0); - if (ret) { - pr_err("IOSS TRACE_CTL Verbosity Set Failed\n"); - goto out; - } - break; - - default: - pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit); - ret = -EINVAL; - break; - } - -out: - mutex_unlock(&(telm_conf->telem_trace_lock)); - return ret; -} - -static const struct telemetry_core_ops telm_pltops = { - .get_trace_verbosity = telemetry_plt_get_trace_verbosity, - .set_trace_verbosity = telemetry_plt_set_trace_verbosity, - .set_sampling_period = telemetry_plt_set_sampling_period, - .get_sampling_period = telemetry_plt_get_sampling_period, - .raw_read_eventlog = telemetry_plt_raw_read_eventlog, - .get_eventconfig = telemetry_plt_get_eventconfig, - .update_events = telemetry_plt_update_events, - .read_eventlog = telemetry_plt_read_eventlog, - .reset_events = telemetry_plt_reset_events, - .add_events = telemetry_plt_add_events, -}; - -static int telemetry_pltdrv_probe(struct platform_device *pdev) -{ - const struct x86_cpu_id *id; - void __iomem *mem; - int ret; - - id = x86_match_cpu(telemetry_cpu_ids); - if (!id) - return -ENODEV; - - telm_conf = (struct telemetry_plt_config *)id->driver_data; - - telm_conf->pmc = dev_get_drvdata(pdev->dev.parent); - - mem = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(mem)) - return PTR_ERR(mem); - - telm_conf->pss_config.regmap = mem; - - mem = devm_platform_ioremap_resource(pdev, 1); - if (IS_ERR(mem)) - return PTR_ERR(mem); - - telm_conf->ioss_config.regmap = mem; - - telm_conf->scu = devm_intel_scu_ipc_dev_get(&pdev->dev); - if (!telm_conf->scu) { - ret = -EPROBE_DEFER; - goto out; - } - - mutex_init(&telm_conf->telem_lock); - mutex_init(&telm_conf->telem_trace_lock); - - ret = telemetry_setup(pdev); - if (ret) - goto out; - - ret = telemetry_set_pltdata(&telm_pltops, telm_conf); - if (ret) { - dev_err(&pdev->dev, "TELEMETRY Set Pltops Failed.\n"); - goto out; - } - - return 0; - -out: - dev_err(&pdev->dev, "TELEMETRY Setup Failed.\n"); - - return ret; -} - -static int telemetry_pltdrv_remove(struct platform_device *pdev) -{ - telemetry_clear_pltdata(); - return 0; -} - -static struct platform_driver telemetry_soc_driver = { - .probe = telemetry_pltdrv_probe, - .remove = telemetry_pltdrv_remove, - .driver = { - .name = DRIVER_NAME, - }, -}; - -static int __init telemetry_module_init(void) -{ - return platform_driver_register(&telemetry_soc_driver); -} - -static void __exit telemetry_module_exit(void) -{ - platform_driver_unregister(&telemetry_soc_driver); -} - -device_initcall(telemetry_module_init); -module_exit(telemetry_module_exit); - -MODULE_AUTHOR("Souvik Kumar Chakravarty "); -MODULE_DESCRIPTION("Intel SoC Telemetry Platform Driver"); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-59-g8ed1b