/*
* Intel SOC Telemetry Platform Driver: Currently supports APL
* Copyright (c) 2015, Intel Corporation.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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.
*
* 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 <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>
#include <asm/intel_pmc_ipc.h>
#include <asm/intel_punit_ipc.h>
#include <asm/intel_telemetry.h>
#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_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_CTRL_WRITE_SIZE 0x4
#define IOSS_TELEM_READ_WORD 0x1
#define IOSS_TELEM_WRITE_FOURBYTES 0x4
#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))
#define TELEM_CPU(model, data) \
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&data }
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", 0