mirror of
git://nv-tegra.nvidia.com/linux-hwpm.git
synced 2025-12-24 02:07:34 +03:00
Add a driver for programming the Tegra SOC HWPM path. SOC HWPM allows performance monitoring of various Tegra IPs. The profiling tests cases are configured through IOCTLs sent by a userspace profiling app. The IOCTLs provide the following features: - IP discovery and reservation - Buffer management - Whitelist query - Register read/write ops Bug 200702306 Bug 3305495 Change-Id: I65003b126e01bd03d856767c55aa2424bcfd11fb Signed-off-by: Adeel Raza <araza@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-t23x/+/2515148 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
137 lines
4.1 KiB
C
137 lines
4.1 KiB
C
/*
|
|
* tegra-soc-hwpm-io.h:
|
|
* This header defines register read/write APIs for the Tegra SOC HWPM driver.
|
|
*
|
|
* Copyright (c) 2021, NVIDIA 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.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef TEGRA_SOC_HWPM_IO_H
|
|
#define TEGRA_SOC_HWPM_IO_H
|
|
|
|
#include "tegra-soc-hwpm.h"
|
|
|
|
/* Mask and shift field_val so it can be written to a register */
|
|
#define HWPM_REG_F(field, field_val) \
|
|
(((field_val) << field##_SHIFT) & field##_MASK)
|
|
|
|
/* Extract a field's value from a register */
|
|
#define HWPM_REG_V(field, reg_val) \
|
|
(((reg_val) & field##_MASK) >> field##_SHIFT)
|
|
|
|
/*
|
|
* Check if field_val is set in reg_val. field_val is already masked and
|
|
* shifted to the correct location.
|
|
*/
|
|
#define HWPM_REG_CHECK(reg_val, field_mask, field_val) \
|
|
(((reg_val) & (field_mask)) == ((field_val) & (field_mask)))
|
|
|
|
/* Mask and shift field_val. Then check if field_val is set in reg_val. */
|
|
#define HWPM_REG_CHECK_F(reg_val, field, field_val) \
|
|
(((reg_val) & field##_MASK) == HWPM_REG_F(field, (field_val)))
|
|
|
|
struct whitelist {
|
|
u64 reg;
|
|
bool zero_in_init;
|
|
};
|
|
|
|
struct hwpm_resource_aperture {
|
|
/*
|
|
* If false, this is a HWPM aperture (PERFRMON, PMA or RTR). Else this
|
|
* is a non-HWPM aperture (ex: VIC).
|
|
*/
|
|
bool is_ip;
|
|
|
|
/*
|
|
* If is_ip == false, specify dt_aperture for readl/writel operations.
|
|
* If is_ip == true, dt_aperture == TEGRA_SOC_HWPM_INVALID_DT.
|
|
*/
|
|
enum tegra_soc_hwpm_dt_aperture dt_aperture;
|
|
|
|
/* Physical aperture */
|
|
u64 start_pa;
|
|
u64 end_pa;
|
|
|
|
/* Whitelist */
|
|
struct whitelist *wlist;
|
|
u64 wlist_size;
|
|
|
|
/* Fake registers for VDK which doesn't have a SOC HWPM fmodel */
|
|
u32 *fake_registers;
|
|
};
|
|
|
|
struct hwpm_resource {
|
|
bool reserved;
|
|
u32 map_size;
|
|
struct hwpm_resource_aperture *map;
|
|
};
|
|
|
|
/* Externs */
|
|
extern struct hwpm_resource hwpm_resources[TERGA_SOC_HWPM_NUM_RESOURCES];
|
|
extern u32 *pma_fake_regs;
|
|
extern u32 *mc_fake_regs[16];
|
|
extern struct hwpm_resource_aperture mss_channel_map[];
|
|
extern struct hwpm_resource_aperture mss_iso_niso_hub_map[];
|
|
extern struct hwpm_resource_aperture mss_mcf_map[];
|
|
extern struct hwpm_resource_aperture pma_map[];
|
|
extern struct hwpm_resource_aperture cmd_slice_rtr_map[];
|
|
|
|
struct hwpm_resource_aperture *find_hwpm_aperture(struct tegra_soc_hwpm *hwpm,
|
|
u64 phys_addr,
|
|
bool check_reservation);
|
|
u32 hwpm_readl(struct tegra_soc_hwpm *hwpm,
|
|
enum tegra_soc_hwpm_dt_aperture dt_aperture,
|
|
u32 reg);
|
|
void hwpm_writel(struct tegra_soc_hwpm *hwpm,
|
|
enum tegra_soc_hwpm_dt_aperture dt_aperture,
|
|
u32 reg,
|
|
u32 val);
|
|
u32 ip_readl(struct tegra_soc_hwpm *hwpm, u64 phys_addr);
|
|
void ip_writel(struct tegra_soc_hwpm *hwpm, u64 phys_addr, u32 val);
|
|
u32 ioctl_readl(struct tegra_soc_hwpm *hwpm,
|
|
struct hwpm_resource_aperture *aperture,
|
|
u64 addr);
|
|
void ioctl_writel(struct tegra_soc_hwpm *hwpm,
|
|
struct hwpm_resource_aperture *aperture,
|
|
u64 addr,
|
|
u32 val);
|
|
int reg_rmw(struct tegra_soc_hwpm *hwpm,
|
|
struct hwpm_resource_aperture *aperture,
|
|
enum tegra_soc_hwpm_dt_aperture dt_aperture,
|
|
u64 addr,
|
|
u32 field_mask,
|
|
u32 field_val,
|
|
bool is_ioctl,
|
|
bool is_ip);
|
|
#define DRIVER_REG_RMW(hwpm, dt_aperture, reg, field, field_val, is_ip) \
|
|
reg_rmw(hwpm, \
|
|
NULL, \
|
|
dt_aperture, \
|
|
reg, \
|
|
field##_MASK, \
|
|
HWPM_REG_F(field, field_val), \
|
|
false, \
|
|
is_ip)
|
|
#define IOCTL_REG_RMW(hwpm, aperture, addr, field_mask, field_val) \
|
|
reg_rmw(hwpm, \
|
|
aperture, \
|
|
aperture->dt_aperture, \
|
|
addr, \
|
|
field_mask, \
|
|
field_val, \
|
|
true, \
|
|
aperture->is_ip)
|
|
|
|
#endif /* TEGRA_SOC_HWPM_IO_H */
|