Files
linux-hwpm/tegra-soc-hwpm-io.h
Adeel Raza 70941decf9 tegra: hwpm: add SOC HWPM driver
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>
2021-05-19 00:33:31 -07:00

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 */