msm: kgsl: Support perfcounter enable via gpu for hwsched

Enabling some perf counter groups needs sending commands
to GPU. Add support to send these commands via HFI for
HW-Sched to enable these perfcounters.

Change-Id: I3441c024cf3a4bc56998d27153201e6cf9236d26
Signed-off-by: Akhil P Oommen <quic_akhilpo@quicinc.com>
Signed-off-by: Hareesh Gundu <quic_hareeshg@quicinc.com>
This commit is contained in:
Akhil P Oommen 2023-02-17 01:36:59 +05:30 committed by Gerrit - the friendly Code Review server
parent 047374a076
commit e22511952a
9 changed files with 112 additions and 46 deletions

View File

@ -2182,7 +2182,7 @@ static const struct adreno_gen7_core adreno_gpu_core_gen7_6_0 = {
ADRENO_IFPC | ADRENO_PREEMPTION | ADRENO_BCL |
ADRENO_ACD | ADRENO_LPAC | ADRENO_DMS,
.gpudev = &adreno_gen7_hwsched_gpudev.base,
.perfcounters = &adreno_gen7_6_0_perfcounters,
.perfcounters = &adreno_gen7_hwsched_perfcounters,
.uche_gmem_alignment = SZ_16M,
.gmem_size = 3 * SZ_1M,
.bus_width = 32,

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _ADRENO_A6XX_H_
@ -351,19 +351,6 @@ bool a6xx_hw_isidle(struct adreno_device *adreno_dev);
void a6xx_spin_idle_debug(struct adreno_device *adreno_dev,
const char *str);
/**
* a6xx_counter_enable - Configure a performance counter for a countable
* @adreno_dev - Adreno device to configure
* @group - Desired performance counter group
* @counter - Desired performance counter in the group
* @countable - Desired countable
*
* Physically set up a counter within a group with the desired countable
* Return 0 on success else error code
*/
int a6xx_counter_enable(struct adreno_device *adreno_dev,
const struct adreno_perfcount_group *group,
unsigned int counter, unsigned int countable);
/**
* a6xx_perfcounter_update - Update the IFPC perfcounter list
* @adreno_dev: An Adreno GPU handle

View File

@ -1306,17 +1306,12 @@ int a6xx_hwsched_cp_init(struct adreno_device *adreno_dev)
int a6xx_hwsched_counter_inline_enable(struct adreno_device *adreno_dev,
const struct adreno_perfcount_group *group,
unsigned int counter, unsigned int countable)
u32 counter, u32 countable)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
struct adreno_perfcount_register *reg = &group->regs[counter];
u32 cmds[A6XX_PERF_COUNTER_ENABLE_DWORDS + 1];
u32 val, cmds[A6XX_PERF_COUNTER_ENABLE_DWORDS + 1];
int ret;
char str[64];
if (!(device->state == KGSL_STATE_ACTIVE))
return a6xx_counter_enable(adreno_dev, group, counter,
countable);
if (group->flags & ADRENO_PERFCOUNTER_GROUP_RESTORE)
a6xx_perfcounter_update(adreno_dev, reg, false);
@ -1328,13 +1323,21 @@ int a6xx_hwsched_counter_inline_enable(struct adreno_device *adreno_dev,
cmds[2] = cp_type4_packet(reg->select, 1);
cmds[3] = countable;
snprintf(str, sizeof(str), "Perfcounter %s/%u/%u start via commands failed\n",
group->name, counter, countable);
ret = a6xx_hfi_send_cmd_async(adreno_dev, cmds);
if (ret)
goto err;
ret = submit_raw_cmds(adreno_dev, cmds, str);
if (!ret)
/* Wait till the register is programmed with the countable */
ret = kgsl_regmap_read_poll_timeout(&device->regmap, reg->select, val,
val == countable, 100, ADRENO_IDLE_TIMEOUT);
if (!ret) {
reg->value = 0;
return ret;
}
err:
dev_err(device->dev, "Perfcounter %s/%u/%u start via commands failed\n",
group->name, counter, countable);
return ret;
}

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _ADRENO_A6XX_HWSCHED_HFI_H_
@ -91,13 +91,12 @@ int a6xx_hwsched_cp_init(struct adreno_device *adreno_dev);
* @counter - Desired performance counter in the group
* @countable - Desired countable
*
* Function is used for adreno cores
* Physically set up a counter within a group with the desired countable
* Return 0 on success else error code
* Return 0 on success or negative error on failure.
*/
int a6xx_hwsched_counter_inline_enable(struct adreno_device *adreno_dev,
const struct adreno_perfcount_group *group,
unsigned int counter, unsigned int countable);
u32 counter, u32 countable);
/**
* a6xx_hfi_send_cmd_async - Send an hfi packet

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "adreno.h"
@ -72,9 +72,9 @@ static u64 a6xx_counter_read_norestore(struct adreno_device *adreno_dev,
return ((((u64) hi) << 32) | lo) + reg->value;
}
int a6xx_counter_enable(struct adreno_device *adreno_dev,
static int a6xx_counter_enable(struct adreno_device *adreno_dev,
const struct adreno_perfcount_group *group,
unsigned int counter, unsigned int countable)
u32 counter, u32 countable)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
struct adreno_perfcount_register *reg = &group->regs[counter];
@ -91,6 +91,16 @@ int a6xx_counter_enable(struct adreno_device *adreno_dev,
return ret;
}
static int a6xx_hwsched_counter_enable(struct adreno_device *adreno_dev,
const struct adreno_perfcount_group *group,
u32 counter, u32 countable)
{
if (!(KGSL_DEVICE(adreno_dev)->state == KGSL_STATE_ACTIVE))
return a6xx_counter_enable(adreno_dev, group, counter, countable);
return a6xx_hwsched_counter_inline_enable(adreno_dev, group, counter, countable);
}
static int a6xx_counter_inline_enable(struct adreno_device *adreno_dev,
const struct adreno_perfcount_group *group,
unsigned int counter, unsigned int countable)
@ -941,7 +951,7 @@ static const struct adreno_perfcount_group a6xx_hwsched_perfcounter_groups
a6xx_counter_enable, a6xx_counter_read, a6xx_counter_load),
A6XX_REGULAR_PERFCOUNTER_GROUP(PC, pc),
A6XX_REGULAR_PERFCOUNTER_GROUP(VFD, vfd),
A6XX_PERFCOUNTER_GROUP(HLSQ, hlsq, a6xx_hwsched_counter_inline_enable,
A6XX_PERFCOUNTER_GROUP(HLSQ, hlsq, a6xx_hwsched_counter_enable,
a6xx_counter_read, a6xx_counter_load),
A6XX_REGULAR_PERFCOUNTER_GROUP(VPC, vpc),
A6XX_REGULAR_PERFCOUNTER_GROUP(CCU, ccu),
@ -950,9 +960,9 @@ static const struct adreno_perfcount_group a6xx_hwsched_perfcounter_groups
A6XX_REGULAR_PERFCOUNTER_GROUP(RAS, ras),
A6XX_REGULAR_PERFCOUNTER_GROUP(LRZ, lrz),
A6XX_REGULAR_PERFCOUNTER_GROUP(UCHE, uche),
A6XX_PERFCOUNTER_GROUP(TP, tp, a6xx_hwsched_counter_inline_enable,
A6XX_PERFCOUNTER_GROUP(TP, tp, a6xx_hwsched_counter_enable,
a6xx_counter_read, a6xx_counter_load),
A6XX_PERFCOUNTER_GROUP(SP, sp, a6xx_hwsched_counter_inline_enable,
A6XX_PERFCOUNTER_GROUP(SP, sp, a6xx_hwsched_counter_enable,
a6xx_counter_read, a6xx_counter_load),
A6XX_REGULAR_PERFCOUNTER_GROUP(RB, rb),
A6XX_REGULAR_PERFCOUNTER_GROUP(VSC, vsc),

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _ADRENO_GEN7_H_
@ -23,7 +23,7 @@ struct gen7_snapshot_block_list;
extern const struct adreno_power_ops gen7_gmu_power_ops;
extern const struct adreno_power_ops gen7_hwsched_power_ops;
extern const struct adreno_perfcounters adreno_gen7_perfcounters;
extern const struct adreno_perfcounters adreno_gen7_6_0_perfcounters;
extern const struct adreno_perfcounters adreno_gen7_hwsched_perfcounters;
struct gen7_gpudev {
struct adreno_gpudev base;
@ -192,6 +192,9 @@ struct gen7_cp_smmu_info {
/* Size of the CP_INIT pm4 stream in dwords */
#define GEN7_CP_INIT_DWORDS 10
/* Size of the perf counter enable pm4 stream in dwords */
#define GEN7_PERF_COUNTER_ENABLE_DWORDS 3
#define GEN7_INT_MASK \
((1 << GEN7_INT_AHBERROR) | \
(1 << GEN7_INT_ATBASYNCFIFOOVERFLOW) | \

View File

@ -2691,3 +2691,41 @@ void gen7_hwsched_context_destroy(struct adreno_device *adreno_dev,
if (drawctxt->gmu_hw_fence_queue.gmuaddr)
gen7_free_gmu_block(to_gen7_gmu(adreno_dev), &drawctxt->gmu_hw_fence_queue);
}
int gen7_hwsched_counter_inline_enable(struct adreno_device *adreno_dev,
const struct adreno_perfcount_group *group,
u32 counter, u32 countable)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
struct adreno_perfcount_register *reg = &group->regs[counter];
u32 val, cmds[GEN7_PERF_COUNTER_ENABLE_DWORDS + 1];
int ret;
if (group->flags & ADRENO_PERFCOUNTER_GROUP_RESTORE)
gen7_perfcounter_update(adreno_dev, reg, false,
FIELD_PREP(GENMASK(13, 12), PIPE_NONE));
cmds[0] = CREATE_MSG_HDR(H2F_MSG_ISSUE_CMD_RAW,
(GEN7_PERF_COUNTER_ENABLE_DWORDS + 1) << 2, HFI_MSG_CMD);
cmds[1] = cp_type7_packet(CP_WAIT_FOR_IDLE, 0);
cmds[2] = cp_type4_packet(reg->select, 1);
cmds[3] = countable;
ret = gen7_hfi_send_cmd_async(adreno_dev, cmds);
if (ret)
goto err;
/* Wait till the register is programmed with the countable */
ret = kgsl_regmap_read_poll_timeout(&device->regmap, reg->select, val,
val == countable, 100, ADRENO_IDLE_TIMEOUT);
if (!ret) {
reg->value = 0;
return ret;
}
err:
dev_err(device->dev, "Perfcounter %s/%u/%u start via commands failed\n",
group->name, counter, countable);
return ret;
}

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _ADRENO_GEN7_HWSCHED_HFI_H_
@ -89,6 +89,20 @@ void gen7_hwsched_hfi_stop(struct adreno_device *adreno_dev);
*/
int gen7_hwsched_cp_init(struct adreno_device *adreno_dev);
/**
* gen7_hwsched_counter_inline_enable - Configure a performance counter for a countable
* @adreno_dev - Adreno device to configure
* @group - Desired performance counter group
* @counter - Desired performance counter in the group
* @countable - Desired countable
*
* Physically set up a counter within a group with the desired countable
* Return 0 on success or negative error on failure.
*/
int gen7_hwsched_counter_inline_enable(struct adreno_device *adreno_dev,
const struct adreno_perfcount_group *group,
u32 counter, u32 countable);
/**
* gen7_hfi_send_cmd_async - Send an hfi packet
* @adreno_dev: Pointer to adreno device structure

View File

@ -1,10 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "adreno.h"
#include "adreno_gen7.h"
#include "adreno_gen7_hwsched_hfi.h"
#include "adreno_perfcounter.h"
#include "adreno_pm4types.h"
#include "kgsl_device.h"
@ -162,6 +164,16 @@ static int gen7_counter_inline_enable(struct adreno_device *adreno_dev,
return ret;
}
static int gen7_hwsched_counter_enable(struct adreno_device *adreno_dev,
const struct adreno_perfcount_group *group,
u32 counter, u32 countable)
{
if (!(KGSL_DEVICE(adreno_dev)->state == KGSL_STATE_ACTIVE))
return gen7_counter_enable(adreno_dev, group, counter, countable);
return gen7_hwsched_counter_inline_enable(adreno_dev, group, counter, countable);
}
static u64 gen7_counter_read(struct adreno_device *adreno_dev,
const struct adreno_perfcount_group *group,
unsigned int counter)
@ -1000,13 +1012,13 @@ static struct adreno_perfcount_register gen7_perfcounters_alwayson[] = {
GEN7_BV_PERFCOUNTER_GROUP(offset, name, \
gen7_counter_enable, gen7_counter_read)
static const struct adreno_perfcount_group gen7_6_0_perfcounter_groups
static const struct adreno_perfcount_group gen7_hwsched_perfcounter_groups
[KGSL_PERFCOUNTER_GROUP_MAX] = {
GEN7_REGULAR_PERFCOUNTER_GROUP(CP, cp),
GEN7_PERFCOUNTER_GROUP_FLAGS(gen7, RBBM, rbbm, 0,
gen7_counter_enable, gen7_counter_read),
GEN7_REGULAR_PERFCOUNTER_GROUP(PC, pc),
GEN7_REGULAR_PERFCOUNTER_GROUP(VFD, vfd),
GEN7_PERFCOUNTER_GROUP(VFD, vfd, gen7_hwsched_counter_enable, gen7_counter_read),
GEN7_PERFCOUNTER_GROUP(HLSQ, hlsq, gen7_counter_br_enable, gen7_counter_read),
GEN7_REGULAR_PERFCOUNTER_GROUP(VPC, vpc),
GEN7_REGULAR_PERFCOUNTER_GROUP(CCU, ccu),
@ -1015,8 +1027,8 @@ static const struct adreno_perfcount_group gen7_6_0_perfcounter_groups
GEN7_PERFCOUNTER_GROUP(RAS, ras, gen7_counter_br_enable, gen7_counter_read),
GEN7_PERFCOUNTER_GROUP(LRZ, lrz, gen7_counter_br_enable, gen7_counter_read),
GEN7_REGULAR_PERFCOUNTER_GROUP(UCHE, gen7_6_0_uche),
GEN7_REGULAR_PERFCOUNTER_GROUP(TP, tp),
GEN7_REGULAR_PERFCOUNTER_GROUP(SP, sp),
GEN7_PERFCOUNTER_GROUP(TP, tp, gen7_hwsched_counter_enable, gen7_counter_read),
GEN7_PERFCOUNTER_GROUP(SP, sp, gen7_hwsched_counter_enable, gen7_counter_read),
GEN7_REGULAR_PERFCOUNTER_GROUP(RB, rb),
GEN7_REGULAR_PERFCOUNTER_GROUP(VSC, vsc),
GEN7_PERFCOUNTER_GROUP_FLAGS(gen7, VBIF, gbif, 0,
@ -1099,7 +1111,7 @@ const struct adreno_perfcounters adreno_gen7_perfcounters = {
ARRAY_SIZE(gen7_perfcounter_groups),
};
const struct adreno_perfcounters adreno_gen7_6_0_perfcounters = {
gen7_6_0_perfcounter_groups,
ARRAY_SIZE(gen7_6_0_perfcounter_groups),
const struct adreno_perfcounters adreno_gen7_hwsched_perfcounters = {
gen7_hwsched_perfcounter_groups,
ARRAY_SIZE(gen7_hwsched_perfcounter_groups),
};