summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2020-08-25 10:51:28 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2020-08-25 10:51:27 -0700
commit02e8ec9605d2e2a5dee7c46a73a77df53d5ce66d (patch)
tree287c656450e8325cb8676eed5214dedab9c94f54 /drivers/gpu
parent45d0ff3112465a5172b4c802ffe021311a5d352b (diff)
parenta6e4cb81280abe3515ad9ed442ae96fd580688d2 (diff)
Merge "msm: kgsl: Mark the scratch buffer as privileged"
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/msm/adreno.c15
-rw-r--r--drivers/gpu/msm/adreno.h4
-rw-r--r--drivers/gpu/msm/adreno_a5xx.c15
-rw-r--r--drivers/gpu/msm/adreno_a5xx.h4
-rw-r--r--drivers/gpu/msm/adreno_pm4types.h4
-rw-r--r--drivers/gpu/msm/adreno_ringbuffer.c46
-rw-r--r--drivers/gpu/msm/adreno_ringbuffer.h5
7 files changed, 78 insertions, 15 deletions
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 000274c5146a..6df074cd2876 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -2827,6 +2827,19 @@ static void adreno_resume_device(struct kgsl_device *device)
adreno_dispatcher_unhalt(device);
}
+u32 adreno_get_ucode_version(const u32 *data)
+{
+ u32 version;
+
+ version = data[1];
+
+ if ((version & 0xf) != 0xa)
+ return version;
+
+ version &= ~0xfff;
+ return version | ((data[3] & 0xfff000) >> 12);
+}
+
static const struct kgsl_functable adreno_functable = {
/* Mandatory functions */
.regread = adreno_regread,
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 1f598bf3d9f8..5434cfb4083b 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-2018,2020 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -942,6 +942,8 @@ int adreno_efuse_read_u32(struct adreno_device *adreno_dev, unsigned int offset,
unsigned int *val);
void adreno_efuse_unmap(struct adreno_device *adreno_dev);
+u32 adreno_get_ucode_version(const u32 *data);
+
#define ADRENO_TARGET(_name, _id) \
static inline int adreno_is_##_name(struct adreno_device *adreno_dev) \
{ \
diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c
index 2514d13b4cdc..c206bdac7d39 100644
--- a/drivers/gpu/msm/adreno_a5xx.c
+++ b/drivers/gpu/msm/adreno_a5xx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2018,2020 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -2177,12 +2177,15 @@ static int a5xx_post_start(struct adreno_device *adreno_dev)
*cmds++ = 0xF;
}
- if (adreno_is_preemption_enabled(adreno_dev))
+ if (adreno_is_preemption_enabled(adreno_dev)) {
cmds += _preemption_init(adreno_dev, rb, cmds, NULL);
+ rb->_wptr = rb->_wptr - (42 - (cmds - start));
+ ret = adreno_ringbuffer_submit_spin_nosync(rb, NULL, 2000);
+ } else {
+ rb->_wptr = rb->_wptr - (42 - (cmds - start));
+ ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000);
+ }
- rb->_wptr = rb->_wptr - (42 - (cmds - start));
-
- ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000);
if (ret)
spin_idle_debug(KGSL_DEVICE(adreno_dev),
"hw initialization failed to idle\n");
@@ -2554,7 +2557,7 @@ static int _load_firmware(struct kgsl_device *device, const char *fwfile,
memcpy(ucode->hostptr, &fw->data[4], fw->size - 4);
*ucode_size = (fw->size - 4) / sizeof(uint32_t);
- *ucode_version = *(unsigned int *)&fw->data[4];
+ *ucode_version = adreno_get_ucode_version((u32 *)fw->data);
done:
release_firmware(fw);
diff --git a/drivers/gpu/msm/adreno_a5xx.h b/drivers/gpu/msm/adreno_a5xx.h
index 08fd16a83f30..8cfd297fa86d 100644
--- a/drivers/gpu/msm/adreno_a5xx.h
+++ b/drivers/gpu/msm/adreno_a5xx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016,2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -112,7 +112,7 @@ void a5xx_crashdump_init(struct adreno_device *adreno_dev);
void a5xx_hwcg_set(struct adreno_device *adreno_dev, bool on);
-#define A5XX_CP_RB_CNTL_DEFAULT (((ilog2(4) << 8) & 0x1F00) | \
+#define A5XX_CP_RB_CNTL_DEFAULT ((1 << 27) | ((ilog2(4) << 8) & 0x1F00) | \
(ilog2(KGSL_RB_DWORDS >> 1) & 0x3F))
/* GPMU interrupt multiplexor */
#define FW_INTR_INFO (0)
diff --git a/drivers/gpu/msm/adreno_pm4types.h b/drivers/gpu/msm/adreno_pm4types.h
index ec2c29b929c1..fdd12f571b2e 100644
--- a/drivers/gpu/msm/adreno_pm4types.h
+++ b/drivers/gpu/msm/adreno_pm4types.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-2016,2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -97,6 +97,8 @@
/* A5XX Enable yield in RB only */
#define CP_YIELD_ENABLE 0x1C
+#define CP_WHERE_AM_I 0x62
+
/* Enable/Disable/Defer A5x global preemption model */
#define CP_PREEMPT_ENABLE_GLOBAL 0x69
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index 3a3777823013..475e5e60163d 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2017,2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-2017,2019-2020 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -138,7 +138,7 @@ void adreno_ringbuffer_submit(struct adreno_ringbuffer *rb,
adreno_ringbuffer_wptr(adreno_dev, rb);
}
-int adreno_ringbuffer_submit_spin(struct adreno_ringbuffer *rb,
+int adreno_ringbuffer_submit_spin_nosync(struct adreno_ringbuffer *rb,
struct adreno_submit_time *time, unsigned int timeout)
{
struct adreno_device *adreno_dev = ADRENO_RB_DEVICE(rb);
@@ -147,6 +147,38 @@ int adreno_ringbuffer_submit_spin(struct adreno_ringbuffer *rb,
return adreno_spin_idle(adreno_dev, timeout);
}
+/*
+ * adreno_ringbuffer_submit_spin() - Submit the cmds and wait until GPU is idle
+ * @rb: Pointer to ringbuffer
+ * @time: Pointer to adreno_submit_time
+ * @timeout: timeout value in ms
+ *
+ * Add commands to the ringbuffer and wait until GPU goes to idle. This routine
+ * inserts a WHERE_AM_I packet to trigger a shadow rptr update. So, use
+ * adreno_ringbuffer_submit_spin_nosync() if the previous cmd in the RB is a
+ * CSY packet because CSY followed by WHERE_AM_I is not legal..
+ */
+int adreno_ringbuffer_submit_spin(struct adreno_ringbuffer *rb,
+ struct adreno_submit_time *time, unsigned int timeout)
+{
+ struct adreno_device *adreno_dev = ADRENO_RB_DEVICE(rb);
+ struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
+ unsigned int *cmds;
+
+ if (adreno_is_a3xx(adreno_dev))
+ return adreno_ringbuffer_submit_spin_nosync(rb, time, timeout);
+
+ cmds = adreno_ringbuffer_allocspace(rb, 3);
+ if (IS_ERR(cmds))
+ return PTR_ERR(cmds);
+
+ *cmds++ = cp_packet(adreno_dev, CP_WHERE_AM_I, 2);
+ cmds += cp_gpuaddr(adreno_dev, cmds,
+ SCRATCH_RPTR_GPU_ADDR(device, rb->id));
+
+ return adreno_ringbuffer_submit_spin_nosync(rb, time, timeout);
+}
+
unsigned int *adreno_ringbuffer_allocspace(struct adreno_ringbuffer *rb,
unsigned int dwords)
{
@@ -273,11 +305,12 @@ int adreno_ringbuffer_probe(struct adreno_device *adreno_dev, bool nopreempt)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
+ unsigned int priv = KGSL_MEMDESC_RANDOM | KGSL_MEMDESC_PRIVILEGED;
int i, status;
if (!adreno_is_a3xx(adreno_dev)) {
status = kgsl_allocate_global(device, &device->scratch,
- PAGE_SIZE, 0, KGSL_MEMDESC_RANDOM, "scratch");
+ PAGE_SIZE, 0, priv, "scratch");
if (status != 0)
return status;
}
@@ -480,6 +513,8 @@ adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb,
if (gpudev->preemption_post_ibsubmit &&
adreno_is_preemption_enabled(adreno_dev))
total_sizedwords += 5;
+ else if (!adreno_is_a3xx(adreno_dev))
+ total_sizedwords += 3;
/*
* a5xx uses 64 bit memory address. pm4 commands that involve read/write
@@ -670,6 +705,11 @@ adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb,
adreno_is_preemption_enabled(adreno_dev))
ringcmds += gpudev->preemption_post_ibsubmit(adreno_dev,
ringcmds);
+ else if (!adreno_is_a3xx(adreno_dev)) {
+ *ringcmds++ = cp_packet(adreno_dev, CP_WHERE_AM_I, 2);
+ ringcmds += cp_gpuaddr(adreno_dev, ringcmds,
+ SCRATCH_RPTR_GPU_ADDR(device, rb->id));
+ }
/*
* If we have more ringbuffer commands than space reserved
diff --git a/drivers/gpu/msm/adreno_ringbuffer.h b/drivers/gpu/msm/adreno_ringbuffer.h
index d64ccbdc846c..a2bf92acf4af 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.h
+++ b/drivers/gpu/msm/adreno_ringbuffer.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2016,2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-2016,2019-2020 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -172,6 +172,9 @@ int adreno_ringbuffer_issuecmds(struct adreno_ringbuffer *rb,
void adreno_ringbuffer_submit(struct adreno_ringbuffer *rb,
struct adreno_submit_time *time);
+int adreno_ringbuffer_submit_spin_nosync(struct adreno_ringbuffer *rb,
+ struct adreno_submit_time *time, unsigned int timeout);
+
int adreno_ringbuffer_submit_spin(struct adreno_ringbuffer *rb,
struct adreno_submit_time *time, unsigned int timeout);