cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

adreno_gpu.h (11837B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * Copyright (C) 2013 Red Hat
      4 * Author: Rob Clark <robdclark@gmail.com>
      5 *
      6 * Copyright (c) 2014,2017, 2019 The Linux Foundation. All rights reserved.
      7 */
      8
      9#ifndef __ADRENO_GPU_H__
     10#define __ADRENO_GPU_H__
     11
     12#include <linux/firmware.h>
     13#include <linux/iopoll.h>
     14
     15#include "msm_gpu.h"
     16
     17#include "adreno_common.xml.h"
     18#include "adreno_pm4.xml.h"
     19
     20extern bool snapshot_debugbus;
     21extern bool allow_vram_carveout;
     22
     23enum {
     24	ADRENO_FW_PM4 = 0,
     25	ADRENO_FW_SQE = 0, /* a6xx */
     26	ADRENO_FW_PFP = 1,
     27	ADRENO_FW_GMU = 1, /* a6xx */
     28	ADRENO_FW_GPMU = 2,
     29	ADRENO_FW_MAX,
     30};
     31
     32enum adreno_quirks {
     33	ADRENO_QUIRK_TWO_PASS_USE_WFI = 1,
     34	ADRENO_QUIRK_FAULT_DETECT_MASK = 2,
     35	ADRENO_QUIRK_LMLOADKILL_DISABLE = 3,
     36};
     37
     38struct adreno_rev {
     39	uint8_t  core;
     40	uint8_t  major;
     41	uint8_t  minor;
     42	uint8_t  patchid;
     43};
     44
     45#define ANY_ID 0xff
     46
     47#define ADRENO_REV(core, major, minor, patchid) \
     48	((struct adreno_rev){ core, major, minor, patchid })
     49
     50struct adreno_gpu_funcs {
     51	struct msm_gpu_funcs base;
     52	int (*get_timestamp)(struct msm_gpu *gpu, uint64_t *value);
     53};
     54
     55struct adreno_reglist {
     56	u32 offset;
     57	u32 value;
     58};
     59
     60extern const struct adreno_reglist a630_hwcg[], a640_hwcg[], a650_hwcg[], a660_hwcg[];
     61
     62struct adreno_info {
     63	struct adreno_rev rev;
     64	uint32_t revn;
     65	const char *name;
     66	const char *fw[ADRENO_FW_MAX];
     67	uint32_t gmem;
     68	enum adreno_quirks quirks;
     69	struct msm_gpu *(*init)(struct drm_device *dev);
     70	const char *zapfw;
     71	u32 inactive_period;
     72	const struct adreno_reglist *hwcg;
     73};
     74
     75const struct adreno_info *adreno_info(struct adreno_rev rev);
     76
     77struct adreno_gpu {
     78	struct msm_gpu base;
     79	struct adreno_rev rev;
     80	const struct adreno_info *info;
     81	uint32_t gmem;  /* actual gmem size */
     82	uint32_t revn;  /* numeric revision name */
     83	uint16_t speedbin;
     84	const struct adreno_gpu_funcs *funcs;
     85
     86	/* interesting register offsets to dump: */
     87	const unsigned int *registers;
     88
     89	/*
     90	 * Are we loading fw from legacy path?  Prior to addition
     91	 * of gpu firmware to linux-firmware, the fw files were
     92	 * placed in toplevel firmware directory, following qcom's
     93	 * android kernel.  But linux-firmware preferred they be
     94	 * placed in a 'qcom' subdirectory.
     95	 *
     96	 * For backwards compatibility, we try first to load from
     97	 * the new path, using request_firmware_direct() to avoid
     98	 * any potential timeout waiting for usermode helper, then
     99	 * fall back to the old path (with direct load).  And
    100	 * finally fall back to request_firmware() with the new
    101	 * path to allow the usermode helper.
    102	 */
    103	enum {
    104		FW_LOCATION_UNKNOWN = 0,
    105		FW_LOCATION_NEW,       /* /lib/firmware/qcom/$fwfile */
    106		FW_LOCATION_LEGACY,    /* /lib/firmware/$fwfile */
    107		FW_LOCATION_HELPER,
    108	} fwloc;
    109
    110	/* firmware: */
    111	const struct firmware *fw[ADRENO_FW_MAX];
    112
    113	/*
    114	 * Register offsets are different between some GPUs.
    115	 * GPU specific offsets will be exported by GPU specific
    116	 * code (a3xx_gpu.c) and stored in this common location.
    117	 */
    118	const unsigned int *reg_offsets;
    119};
    120#define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base)
    121
    122struct adreno_ocmem {
    123	struct ocmem *ocmem;
    124	unsigned long base;
    125	void *hdl;
    126};
    127
    128/* platform config data (ie. from DT, or pdata) */
    129struct adreno_platform_config {
    130	struct adreno_rev rev;
    131};
    132
    133#define ADRENO_IDLE_TIMEOUT msecs_to_jiffies(1000)
    134
    135#define spin_until(X) ({                                   \
    136	int __ret = -ETIMEDOUT;                            \
    137	unsigned long __t = jiffies + ADRENO_IDLE_TIMEOUT; \
    138	do {                                               \
    139		if (X) {                                   \
    140			__ret = 0;                         \
    141			break;                             \
    142		}                                          \
    143	} while (time_before(jiffies, __t));               \
    144	__ret;                                             \
    145})
    146
    147bool adreno_cmp_rev(struct adreno_rev rev1, struct adreno_rev rev2);
    148
    149static inline bool adreno_is_a2xx(struct adreno_gpu *gpu)
    150{
    151	return (gpu->revn < 300);
    152}
    153
    154static inline bool adreno_is_a20x(struct adreno_gpu *gpu)
    155{
    156	return (gpu->revn < 210);
    157}
    158
    159static inline bool adreno_is_a225(struct adreno_gpu *gpu)
    160{
    161	return gpu->revn == 225;
    162}
    163
    164static inline bool adreno_is_a305(struct adreno_gpu *gpu)
    165{
    166	return gpu->revn == 305;
    167}
    168
    169static inline bool adreno_is_a306(struct adreno_gpu *gpu)
    170{
    171	/* yes, 307, because a305c is 306 */
    172	return gpu->revn == 307;
    173}
    174
    175static inline bool adreno_is_a320(struct adreno_gpu *gpu)
    176{
    177	return gpu->revn == 320;
    178}
    179
    180static inline bool adreno_is_a330(struct adreno_gpu *gpu)
    181{
    182	return gpu->revn == 330;
    183}
    184
    185static inline bool adreno_is_a330v2(struct adreno_gpu *gpu)
    186{
    187	return adreno_is_a330(gpu) && (gpu->rev.patchid > 0);
    188}
    189
    190static inline int adreno_is_a405(struct adreno_gpu *gpu)
    191{
    192	return gpu->revn == 405;
    193}
    194
    195static inline int adreno_is_a420(struct adreno_gpu *gpu)
    196{
    197	return gpu->revn == 420;
    198}
    199
    200static inline int adreno_is_a430(struct adreno_gpu *gpu)
    201{
    202       return gpu->revn == 430;
    203}
    204
    205static inline int adreno_is_a506(struct adreno_gpu *gpu)
    206{
    207	return gpu->revn == 506;
    208}
    209
    210static inline int adreno_is_a508(struct adreno_gpu *gpu)
    211{
    212	return gpu->revn == 508;
    213}
    214
    215static inline int adreno_is_a509(struct adreno_gpu *gpu)
    216{
    217	return gpu->revn == 509;
    218}
    219
    220static inline int adreno_is_a510(struct adreno_gpu *gpu)
    221{
    222	return gpu->revn == 510;
    223}
    224
    225static inline int adreno_is_a512(struct adreno_gpu *gpu)
    226{
    227	return gpu->revn == 512;
    228}
    229
    230static inline int adreno_is_a530(struct adreno_gpu *gpu)
    231{
    232	return gpu->revn == 530;
    233}
    234
    235static inline int adreno_is_a540(struct adreno_gpu *gpu)
    236{
    237	return gpu->revn == 540;
    238}
    239
    240static inline int adreno_is_a618(struct adreno_gpu *gpu)
    241{
    242       return gpu->revn == 618;
    243}
    244
    245static inline int adreno_is_a630(struct adreno_gpu *gpu)
    246{
    247       return gpu->revn == 630;
    248}
    249
    250static inline int adreno_is_a640_family(struct adreno_gpu *gpu)
    251{
    252	return (gpu->revn == 640) || (gpu->revn == 680);
    253}
    254
    255static inline int adreno_is_a650(struct adreno_gpu *gpu)
    256{
    257       return gpu->revn == 650;
    258}
    259
    260static inline int adreno_is_7c3(struct adreno_gpu *gpu)
    261{
    262	/* The order of args is important here to handle ANY_ID correctly */
    263       return adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), gpu->rev);
    264}
    265
    266static inline int adreno_is_a660(struct adreno_gpu *gpu)
    267{
    268       return gpu->revn == 660;
    269}
    270
    271static inline int adreno_is_a660_family(struct adreno_gpu *gpu)
    272{
    273       return adreno_is_a660(gpu) || adreno_is_7c3(gpu);
    274}
    275
    276/* check for a650, a660, or any derivatives */
    277static inline int adreno_is_a650_family(struct adreno_gpu *gpu)
    278{
    279       return gpu->revn == 650 || gpu->revn == 620 ||
    280	       adreno_is_a660_family(gpu);
    281}
    282
    283int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
    284		     uint32_t param, uint64_t *value, uint32_t *len);
    285int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
    286		     uint32_t param, uint64_t value, uint32_t len);
    287const struct firmware *adreno_request_fw(struct adreno_gpu *adreno_gpu,
    288		const char *fwname);
    289struct drm_gem_object *adreno_fw_create_bo(struct msm_gpu *gpu,
    290		const struct firmware *fw, u64 *iova);
    291int adreno_hw_init(struct msm_gpu *gpu);
    292void adreno_recover(struct msm_gpu *gpu);
    293void adreno_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring, u32 reg);
    294bool adreno_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
    295#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
    296void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
    297		struct drm_printer *p);
    298#endif
    299void adreno_dump_info(struct msm_gpu *gpu);
    300void adreno_dump(struct msm_gpu *gpu);
    301void adreno_wait_ring(struct msm_ringbuffer *ring, uint32_t ndwords);
    302struct msm_ringbuffer *adreno_active_ring(struct msm_gpu *gpu);
    303
    304int adreno_gpu_ocmem_init(struct device *dev, struct adreno_gpu *adreno_gpu,
    305			  struct adreno_ocmem *ocmem);
    306void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *ocmem);
    307
    308int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
    309		struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs,
    310		int nr_rings);
    311void adreno_gpu_cleanup(struct adreno_gpu *gpu);
    312int adreno_load_fw(struct adreno_gpu *adreno_gpu);
    313
    314void adreno_gpu_state_destroy(struct msm_gpu_state *state);
    315
    316int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state);
    317int adreno_gpu_state_put(struct msm_gpu_state *state);
    318void adreno_show_object(struct drm_printer *p, void **ptr, int len,
    319		bool *encoded);
    320
    321/*
    322 * Common helper function to initialize the default address space for arm-smmu
    323 * attached targets
    324 */
    325struct msm_gem_address_space *
    326adreno_iommu_create_address_space(struct msm_gpu *gpu,
    327		struct platform_device *pdev);
    328
    329void adreno_set_llc_attributes(struct iommu_domain *iommu);
    330
    331int adreno_read_speedbin(struct device *dev, u32 *speedbin);
    332
    333/*
    334 * For a5xx and a6xx targets load the zap shader that is used to pull the GPU
    335 * out of secure mode
    336 */
    337int adreno_zap_shader_load(struct msm_gpu *gpu, u32 pasid);
    338
    339/* ringbuffer helpers (the parts that are adreno specific) */
    340
    341static inline void
    342OUT_PKT0(struct msm_ringbuffer *ring, uint16_t regindx, uint16_t cnt)
    343{
    344	adreno_wait_ring(ring, cnt+1);
    345	OUT_RING(ring, CP_TYPE0_PKT | ((cnt-1) << 16) | (regindx & 0x7FFF));
    346}
    347
    348/* no-op packet: */
    349static inline void
    350OUT_PKT2(struct msm_ringbuffer *ring)
    351{
    352	adreno_wait_ring(ring, 1);
    353	OUT_RING(ring, CP_TYPE2_PKT);
    354}
    355
    356static inline void
    357OUT_PKT3(struct msm_ringbuffer *ring, uint8_t opcode, uint16_t cnt)
    358{
    359	adreno_wait_ring(ring, cnt+1);
    360	OUT_RING(ring, CP_TYPE3_PKT | ((cnt-1) << 16) | ((opcode & 0xFF) << 8));
    361}
    362
    363static inline u32 PM4_PARITY(u32 val)
    364{
    365	return (0x9669 >> (0xF & (val ^
    366		(val >> 4) ^ (val >> 8) ^ (val >> 12) ^
    367		(val >> 16) ^ ((val) >> 20) ^ (val >> 24) ^
    368		(val >> 28)))) & 1;
    369}
    370
    371/* Maximum number of values that can be executed for one opcode */
    372#define TYPE4_MAX_PAYLOAD 127
    373
    374#define PKT4(_reg, _cnt) \
    375	(CP_TYPE4_PKT | ((_cnt) << 0) | (PM4_PARITY((_cnt)) << 7) | \
    376	 (((_reg) & 0x3FFFF) << 8) | (PM4_PARITY((_reg)) << 27))
    377
    378static inline void
    379OUT_PKT4(struct msm_ringbuffer *ring, uint16_t regindx, uint16_t cnt)
    380{
    381	adreno_wait_ring(ring, cnt + 1);
    382	OUT_RING(ring, PKT4(regindx, cnt));
    383}
    384
    385static inline void
    386OUT_PKT7(struct msm_ringbuffer *ring, uint8_t opcode, uint16_t cnt)
    387{
    388	adreno_wait_ring(ring, cnt + 1);
    389	OUT_RING(ring, CP_TYPE7_PKT | (cnt << 0) | (PM4_PARITY(cnt) << 15) |
    390		((opcode & 0x7F) << 16) | (PM4_PARITY(opcode) << 23));
    391}
    392
    393struct msm_gpu *a2xx_gpu_init(struct drm_device *dev);
    394struct msm_gpu *a3xx_gpu_init(struct drm_device *dev);
    395struct msm_gpu *a4xx_gpu_init(struct drm_device *dev);
    396struct msm_gpu *a5xx_gpu_init(struct drm_device *dev);
    397struct msm_gpu *a6xx_gpu_init(struct drm_device *dev);
    398
    399static inline uint32_t get_wptr(struct msm_ringbuffer *ring)
    400{
    401	return (ring->cur - ring->start) % (MSM_GPU_RINGBUFFER_SZ >> 2);
    402}
    403
    404/*
    405 * Given a register and a count, return a value to program into
    406 * REG_CP_PROTECT_REG(n) - this will block both reads and writes for _len
    407 * registers starting at _reg.
    408 *
    409 * The register base needs to be a multiple of the length. If it is not, the
    410 * hardware will quietly mask off the bits for you and shift the size. For
    411 * example, if you intend the protection to start at 0x07 for a length of 4
    412 * (0x07-0x0A) the hardware will actually protect (0x04-0x07) which might
    413 * expose registers you intended to protect!
    414 */
    415#define ADRENO_PROTECT_RW(_reg, _len) \
    416	((1 << 30) | (1 << 29) | \
    417	((ilog2((_len)) & 0x1F) << 24) | (((_reg) << 2) & 0xFFFFF))
    418
    419/*
    420 * Same as above, but allow reads over the range. For areas of mixed use (such
    421 * as performance counters) this allows us to protect a much larger range with a
    422 * single register
    423 */
    424#define ADRENO_PROTECT_RDONLY(_reg, _len) \
    425	((1 << 29) \
    426	((ilog2((_len)) & 0x1F) << 24) | (((_reg) << 2) & 0xFFFFF))
    427
    428
    429#define gpu_poll_timeout(gpu, addr, val, cond, interval, timeout) \
    430	readl_poll_timeout((gpu)->mmio + ((addr) << 2), val, cond, \
    431		interval, timeout)
    432
    433#endif /* __ADRENO_GPU_H__ */