msm: kgsl: Make coresight optional

Make coresight support conditional on a new Kconfig option. Support this
by moving the code around a bit and out of the generic headers to make
possible to omit the coresight code when the support isn't available.

This allows us to omit coresight when CONFIG_CORESIGHT isn't enabled
and optionally to remove it at the KGSL level too.

Change-Id: Ic0dedbad2a55df4acf1b8c6e15e5b1b39f08a832
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
This commit is contained in:
Jordan Crouse 2019-10-14 10:40:59 -06:00
parent 7a6368ee0b
commit c1cc28e662
8 changed files with 176 additions and 136 deletions

View File

@ -13,3 +13,11 @@ config QCOM_ADRENO_DEFAULT_GOVERNOR
string "devfreq governor for the adreno core"
default "simple_ondemand"
depends on QCOM_KGSL
config QCOM_KGSL_CORESIGHT
bool "Enable coresight support for the Adreno GPU"
depends on QCOM_KGSL && CORESIGHT
help
When enabled, the Adreno GPU is available as a source for Coresight
data. On a6xx targets there are two sources available for the GX and
CX domains respectively. Debug kernels should say 'Y' here.

View File

@ -37,7 +37,6 @@ msm_kgsl-y += \
adreno_a6xx_preempt.o \
adreno_a6xx_rgmu.o \
adreno_a6xx_snapshot.o \
adreno_coresight.o \
adreno_cp_parser.o \
adreno_dispatch.o \
adreno_drawctxt.o \
@ -49,5 +48,6 @@ msm_kgsl-y += \
adreno_trace.o
msm_kgsl-$(CONFIG_COMPAT) += adreno_compat.o
msm_kgsl-$(CONFIG_QCOM_KGSL_CORESIGHT) += adreno_coresight.o
msm_kgsl-$(CONFIG_DEBUG_FS) += adreno_debugfs.o adreno_profile.o
msm_kgsl-$(CONFIG_ARM_SMMU) += adreno_iommu.o

View File

@ -5,6 +5,7 @@
#ifndef __ADRENO_H
#define __ADRENO_H
#include "adreno_coresight.h"
#include "adreno_dispatch.h"
#include "adreno_drawctxt.h"
#include "adreno_perfcounter.h"
@ -364,12 +365,6 @@ struct adreno_gpu_core {
u32 bus_width;
};
enum gpu_coresight_sources {
GPU_CORESIGHT_GX = 0,
GPU_CORESIGHT_CX = 1,
GPU_CORESIGHT_MAX,
};
/**
* struct adreno_device - The mothership structure for all adreno related info
* @dev: Reference to struct kgsl_device
@ -520,7 +515,7 @@ struct adreno_device {
unsigned int highest_bank_bit;
unsigned int quirks;
struct coresight_device *csdev[GPU_CORESIGHT_MAX];
struct coresight_device *csdev[2];
uint32_t gpmu_throttle_counters[ADRENO_GPMU_THROTTLE_COUNTERS];
struct work_struct irq_storm_work;
@ -733,53 +728,6 @@ struct adreno_vbif_snapshot_registers {
const int count;
};
/**
* struct adreno_coresight_register - Definition for a coresight (tracebus)
* debug register
* @offset: Offset of the debug register in the KGSL mmio region
* @initial: Default value to write when coresight is enabled
* @value: Current shadow value of the register (to be reprogrammed after power
* collapse)
*/
struct adreno_coresight_register {
unsigned int offset;
unsigned int initial;
unsigned int value;
};
struct adreno_coresight_attr {
struct device_attribute attr;
struct adreno_coresight_register *reg;
};
ssize_t adreno_coresight_show_register(struct device *device,
struct device_attribute *attr, char *buf);
ssize_t adreno_coresight_store_register(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size);
#define ADRENO_CORESIGHT_ATTR(_attrname, _reg) \
struct adreno_coresight_attr coresight_attr_##_attrname = { \
__ATTR(_attrname, 0644, \
adreno_coresight_show_register, \
adreno_coresight_store_register), \
(_reg), }
/**
* struct adreno_coresight - GPU specific coresight definition
* @registers - Array of GPU specific registers to configure trace bus output
* @count - Number of registers in the array
* @groups - Pointer to an attribute list of control files
* @atid - The unique ATID value of the coresight device
*/
struct adreno_coresight {
struct adreno_coresight_register *registers;
unsigned int count;
const struct attribute_group **groups;
unsigned int atid;
};
struct adreno_irq_funcs {
void (*func)(struct adreno_device *adreno_dev, int mask);
};
@ -819,7 +767,7 @@ struct adreno_gpudev {
struct adreno_perfcounters *perfcounters;
struct adreno_coresight *coresight[GPU_CORESIGHT_MAX];
struct adreno_coresight *coresight[2];
struct adreno_irq *irq;
int num_prio_levels;
@ -988,13 +936,6 @@ void adreno_fault_skipcmd_detached(struct adreno_device *adreno_dev,
struct adreno_context *drawctxt,
struct kgsl_drawobj *drawobj);
void adreno_coresight_init(struct adreno_device *adreno_dev);
void adreno_coresight_start(struct adreno_device *adreno_dev);
void adreno_coresight_stop(struct adreno_device *adreno_dev);
void adreno_coresight_remove(struct adreno_device *adreno_dev);
bool adreno_hw_isidle(struct adreno_device *adreno_dev);
void adreno_fault_detect_start(struct adreno_device *adreno_dev);

View File

@ -1142,6 +1142,7 @@ static void a3xx_start(struct adreno_device *adreno_dev)
}
#ifdef CONFIG_QCOM_KGSL_CORESIGHT
static struct adreno_coresight_register a3xx_coresight_registers[] = {
{ A3XX_RBBM_DEBUG_BUS_CTL, 0x0001093F },
{ A3XX_RBBM_EXT_TRACE_STOP_CNT, 0x00017fff },
@ -1191,6 +1192,7 @@ static struct adreno_coresight a3xx_coresight = {
.count = ARRAY_SIZE(a3xx_coresight_registers),
.groups = a3xx_coresight_groups,
};
#endif
static unsigned int a3xx_int_bits[ADRENO_INT_BITS_MAX] = {
ADRENO_INT_DEFINE(ADRENO_INT_RBBM_AHB_ERROR, A3XX_INT_RBBM_AHB_ERROR),
@ -1445,6 +1447,8 @@ struct adreno_gpudev adreno_a3xx_gpudev = {
.microcode_read = a3xx_microcode_read,
.start = a3xx_start,
.snapshot = a3xx_snapshot,
#ifdef CONFIG_QCOM_KGSL_CORESIGHT
.coresight = {&a3xx_coresight},
#endif
.clk_set_options = a3xx_clk_set_options,
};

View File

@ -2857,6 +2857,7 @@ static struct adreno_irq a5xx_irq = {
.mask = A5XX_INT_MASK,
};
#ifdef CONFIG_QCOM_KGSL_CORESIGHT
static struct adreno_coresight_register a5xx_coresight_registers[] = {
{ A5XX_RBBM_CFG_DBGBUS_SEL_A },
{ A5XX_RBBM_CFG_DBGBUS_SEL_B },
@ -3049,13 +3050,16 @@ static struct adreno_coresight a5xx_coresight = {
.count = ARRAY_SIZE(a5xx_coresight_registers),
.groups = a5xx_coresight_groups,
};
#endif
struct adreno_gpudev adreno_a5xx_gpudev = {
.reg_offsets = a5xx_register_offsets,
.int_bits = a5xx_int_bits,
.ft_perf_counters = a5xx_ft_perf_counters,
.ft_perf_counters_count = ARRAY_SIZE(a5xx_ft_perf_counters),
#ifdef CONFIG_QCOM_KGSL_CORESIGHT
.coresight = {&a5xx_coresight},
#endif
.start = a5xx_start,
.snapshot = a5xx_snapshot,
.irq = &a5xx_irq,

View File

@ -1428,6 +1428,7 @@ static struct adreno_irq a6xx_irq = {
.mask = A6XX_INT_MASK,
};
#ifdef CONFIG_QCOM_KGSL_CORESIGHT
static struct adreno_coresight_register a6xx_coresight_regs[] = {
{ A6XX_DBGC_CFG_DBGBUS_SEL_A },
{ A6XX_DBGC_CFG_DBGBUS_SEL_B },
@ -1841,6 +1842,7 @@ static struct adreno_coresight a6xx_coresight_cx = {
.count = ARRAY_SIZE(a6xx_coresight_regs_cx),
.groups = a6xx_coresight_groups_cx,
};
#endif
static struct adreno_perfcount_register a6xx_perfcounters_cp[] = {
{ KGSL_PERFCOUNTER_NOT_USED, 0, 0, A6XX_RBBM_PERFCTR_CP_0_LO,
@ -2614,6 +2616,8 @@ struct adreno_gpudev adreno_a6xx_gpudev = {
.sptprac_is_on = a6xx_sptprac_is_on,
.ccu_invalidate = a6xx_ccu_invalidate,
.perfcounter_update = a6xx_perfcounter_update,
#ifdef CONFIG_QCOM_KGSL_CORESIGHT
.coresight = {&a6xx_coresight, &a6xx_coresight_cx},
#endif
.clk_set_options = a6xx_clk_set_options,
};

View File

@ -9,6 +9,11 @@
#include "adreno.h"
enum gpu_coresight_sources {
GPU_CORESIGHT_GX = 0,
GPU_CORESIGHT_CX = 1,
};
#define TO_ADRENO_CORESIGHT_ATTR(_attr) \
container_of(_attr, struct adreno_coresight_attr, attr)
@ -129,18 +134,10 @@ out:
return size;
}
/**
* adreno_coresight_disable() - Generic function to disable coresight debugging
* @csdev: Pointer to coresight's device struct
*
* This is a generic function to disable coresight debug bus on adreno
* devices. This should be used in all cases of disabling
* coresight debug bus for adreno devices. This function in turn calls
* the adreno device specific function through the gpudev hook.
* This function is registered as the coresight disable function
* with coresight driver. It should only be called through coresight driver
* as that would ensure that the necessary setup required to be done on
* coresight driver's part is also done.
/*
* This is a generic function to disable coresight debug bus on Adreno
* devices. This function in turn calls the device specific function
* through the gpudev hook.
*/
static void adreno_coresight_disable(struct coresight_device *csdev,
struct perf_event *event)
@ -190,12 +187,6 @@ static void adreno_coresight_disable(struct coresight_device *csdev,
mutex_unlock(&device->mutex);
}
/**
* _adreno_coresight_get_and_clear(): Save the current value of coresight
* registers and clear the registers subsequently. Clearing registers
* has the effect of disabling coresight.
* @adreno_dev: Pointer to adreno device struct
*/
static int _adreno_coresight_get_and_clear(struct adreno_device *adreno_dev,
int cs_id)
{
@ -254,17 +245,7 @@ static int _adreno_coresight_set(struct adreno_device *adreno_dev, int cs_id)
}
return 0;
}
/**
* adreno_coresight_enable() - Generic function to enable coresight debugging
* @csdev: Pointer to coresight's device struct
*
* This is a generic function to enable coresight debug bus on adreno
* devices. This should be used in all cases of enabling
* coresight debug bus for adreno devices. This function is registered as the
* coresight enable function with coresight driver. It should only be called
* through coresight driver as that would ensure that the necessary setup
* required to be done on coresight driver's part is also done.
*/
/* Generic function to enable coresight debug bus on adreno devices */
static int adreno_coresight_enable(struct coresight_device *csdev,
struct perf_event *event, u32 mode)
{
@ -321,51 +302,22 @@ static int adreno_coresight_enable(struct coresight_device *csdev,
return ret;
}
/**
* adreno_coresight_stop() - Reprogram coresight registers after power collapse
* @adreno_dev: Pointer to the adreno device structure
*
* Cache the current coresight register values so they can be restored after
* power collapse
*/
void adreno_coresight_stop(struct adreno_device *adreno_dev)
{
int i, adreno_dev_flag = -EINVAL;
if (test_bit(ADRENO_DEVICE_CORESIGHT, &adreno_dev->priv))
_adreno_coresight_get_and_clear(adreno_dev, GPU_CORESIGHT_GX);
for (i = 0; i < GPU_CORESIGHT_MAX; ++i) {
if (i == GPU_CORESIGHT_GX)
adreno_dev_flag = ADRENO_DEVICE_CORESIGHT;
else if (i == GPU_CORESIGHT_CX)
adreno_dev_flag = ADRENO_DEVICE_CORESIGHT_CX;
else
return;
if (test_bit(adreno_dev_flag, &adreno_dev->priv))
_adreno_coresight_get_and_clear(adreno_dev, i);
}
if (test_bit(ADRENO_DEVICE_CORESIGHT_CX, &adreno_dev->priv))
_adreno_coresight_get_and_clear(adreno_dev, GPU_CORESIGHT_CX);
}
/**
* adreno_coresight_start() - Reprogram coresight registers after power collapse
* @adreno_dev: Pointer to the adreno device structure
*
* Reprogram the cached values to the coresight registers on power up
*/
void adreno_coresight_start(struct adreno_device *adreno_dev)
{
int i, adreno_dev_flag = -EINVAL;
if (test_bit(ADRENO_DEVICE_CORESIGHT, &adreno_dev->priv))
_adreno_coresight_set(adreno_dev, GPU_CORESIGHT_GX);
for (i = 0; i < GPU_CORESIGHT_MAX; ++i) {
if (i == GPU_CORESIGHT_GX)
adreno_dev_flag = ADRENO_DEVICE_CORESIGHT;
else if (i == GPU_CORESIGHT_CX)
adreno_dev_flag = ADRENO_DEVICE_CORESIGHT_CX;
else
return;
if (test_bit(adreno_dev_flag, &adreno_dev->priv))
_adreno_coresight_set(adreno_dev, i);
}
if (test_bit(ADRENO_DEVICE_CORESIGHT_CX, &adreno_dev->priv))
_adreno_coresight_set(adreno_dev, GPU_CORESIGHT_CX);
}
static int adreno_coresight_trace_id(struct coresight_device *csdev)
@ -396,12 +348,9 @@ void adreno_coresight_remove(struct adreno_device *adreno_dev)
{
int i;
for (i = 0; i < ARRAY_SIZE(adreno_dev->csdev); i++) {
if (!IS_ERR_OR_NULL(adreno_dev->csdev[i])) {
for (i = 0; i < ARRAY_SIZE(adreno_dev->csdev); i++)
if (!IS_ERR_OR_NULL(adreno_dev->csdev[i]))
coresight_unregister(adreno_dev->csdev[i]);
adreno_dev->csdev[i] = NULL;
}
}
}
static struct coresight_device *
@ -437,7 +386,6 @@ adreno_coresight_dev_probe(struct kgsl_device *device,
void adreno_coresight_init(struct adreno_device *adreno_dev)
{
int ret = 0;
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
int i = 0;
@ -456,5 +404,4 @@ void adreno_coresight_init(struct adreno_device *adreno_dev)
}
of_node_put(node);
return ret;
}

View File

@ -0,0 +1,132 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
#ifndef _ADRENO_CORESIGHT_H_
#define _ADRENO_CORESIGHT_H_
#include <linux/device.h>
struct adreno_device;
/**
* struct adreno_coresight_register - Definition for a coresight (tracebus)
* debug register
*/
struct adreno_coresight_register {
/** @offset: Offset of the debug register in the KGSL register space */
unsigned int offset;
/** @initial: Default value to write when coresight is enabled */
unsigned int initial;
/**
* @value: Current shadow value of the register (to be reprogrammed
* after power collapse)
*/
unsigned int value;
};
/**
* struct adreno_coresight_attr - Local attribute struct for coresight sysfs
*
* files
*/
struct adreno_coresight_attr {
/** @attr: Base device attribute */
struct device_attribute attr;
/**
* @reg: Pointer to the &struct adreno_coresight_register definition
* for this register
*/
struct adreno_coresight_register *reg;
};
/**
* adreno_coresight_show_register - Callback function for sysfs show
* @device: Pointer to a device handle
* @attr: Pointer to the device attribute
* @buf: Contains the output buffer for sysfs
*
* Callback function to write the value of the register into the sysfs node.
* Return: The size of the data written to the buffer or negative on error.
*/
ssize_t adreno_coresight_show_register(struct device *device,
struct device_attribute *attr, char *buf);
/**
* adreno_coresight_show_register - Callback function for sysfs store
* @device: Pointer to a device handle
* @attr: Pointer to the device attribute
* @buf: Contains the input buffer for sysfs
* @size: Size of the data stored in buf
*
* Callback function to read the value of a register from a sysfs node.
* Return: The size of the data consumed or negative on error.
*/
ssize_t adreno_coresight_store_register(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size);
#define ADRENO_CORESIGHT_ATTR(_attrname, _reg) \
struct adreno_coresight_attr coresight_attr_##_attrname = { \
__ATTR(_attrname, 0644, \
adreno_coresight_show_register, \
adreno_coresight_store_register), \
(_reg), }
/**
* struct adreno_coresight - GPU specific coresight definition
*/
struct adreno_coresight {
/**
* @registers: Array of GPU specific registers to configure trace
* bus output
*/
struct adreno_coresight_register *registers;
/** @count: Number of registers in the array */
unsigned int count;
/** @groups: Pointer to an attribute list of control files */
const struct attribute_group **groups;
/** @atid: The unique ATID value of the coresight device */
unsigned int atid;
};
#ifdef CONFIG_QCOM_KGSL_CORESIGHT
/**
* adreno_coresight_init - Initialize coresight for the GPU device
* @adreno_dev: An Adreno GPU device handle
*
* Initialize devices for the GPU target.
*/
void adreno_coresight_init(struct adreno_device *adreno_dev);
/**
* adreno_coresight_start - Reprogram coresight registers after power collapse
* @adreno_dev: An Adreno GPU device handle
*
* Reprogram the cached values to the coresight registers on power up.
*/
void adreno_coresight_start(struct adreno_device *adreno_dev);
/**
* adreno_coresight_stop - Reprogram coresight registers after power collapse
* @adreno_dev: An Adreno GPU device handle
*
* Cache the current coresight register values so they can be restored after
* power collapse.
*/
void adreno_coresight_stop(struct adreno_device *adreno_dev);
/**
* adreno_coresight_remove - Destroy active coresight devices
* @adreno_dev: An Adreno GPU device handle
*
* Destroy any active coresight devices.
*/
void adreno_coresight_remove(struct adreno_device *adreno_dev);
#else
static inline void adreno_coresight_init(struct adreno_device *adreno_dev) { }
static inline void adreno_coresight_start(struct adreno_device *adreno_dev) { }
static inline void adreno_coresight_stop(struct adreno_device *adreno_dev) { }
static inline void adreno_coresight_remove(struct adreno_device *adreno_dev) { }
#endif
#endif