|
@@ -15,7 +15,7 @@
|
|
#include <linux/cpumask.h>
|
|
#include <linux/cpumask.h>
|
|
#include <linux/qcom_scm.h>
|
|
#include <linux/qcom_scm.h>
|
|
#include <linux/dma-mapping.h>
|
|
#include <linux/dma-mapping.h>
|
|
-#include <linux/of_reserved_mem.h>
|
|
|
|
|
|
+#include <linux/of_address.h>
|
|
#include <linux/soc/qcom/mdt_loader.h>
|
|
#include <linux/soc/qcom/mdt_loader.h>
|
|
#include "msm_gem.h"
|
|
#include "msm_gem.h"
|
|
#include "msm_mmu.h"
|
|
#include "msm_mmu.h"
|
|
@@ -26,16 +26,34 @@ static void a5xx_dump(struct msm_gpu *gpu);
|
|
|
|
|
|
#define GPU_PAS_ID 13
|
|
#define GPU_PAS_ID 13
|
|
|
|
|
|
-#if IS_ENABLED(CONFIG_QCOM_MDT_LOADER)
|
|
|
|
-
|
|
|
|
static int zap_shader_load_mdt(struct device *dev, const char *fwname)
|
|
static int zap_shader_load_mdt(struct device *dev, const char *fwname)
|
|
{
|
|
{
|
|
const struct firmware *fw;
|
|
const struct firmware *fw;
|
|
|
|
+ struct device_node *np;
|
|
|
|
+ struct resource r;
|
|
phys_addr_t mem_phys;
|
|
phys_addr_t mem_phys;
|
|
ssize_t mem_size;
|
|
ssize_t mem_size;
|
|
void *mem_region = NULL;
|
|
void *mem_region = NULL;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
|
|
+ if (!IS_ENABLED(CONFIG_ARCH_QCOM))
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
|
|
+ np = of_get_child_by_name(dev->of_node, "zap-shader");
|
|
|
|
+ if (!np)
|
|
|
|
+ return -ENODEV;
|
|
|
|
+
|
|
|
|
+ np = of_parse_phandle(np, "memory-region", 0);
|
|
|
|
+ if (!np)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
|
|
+ ret = of_address_to_resource(np, 0, &r);
|
|
|
|
+ if (ret)
|
|
|
|
+ return ret;
|
|
|
|
+
|
|
|
|
+ mem_phys = r.start;
|
|
|
|
+ mem_size = resource_size(&r);
|
|
|
|
+
|
|
/* Request the MDT file for the firmware */
|
|
/* Request the MDT file for the firmware */
|
|
ret = request_firmware(&fw, fwname, dev);
|
|
ret = request_firmware(&fw, fwname, dev);
|
|
if (ret) {
|
|
if (ret) {
|
|
@@ -51,7 +69,7 @@ static int zap_shader_load_mdt(struct device *dev, const char *fwname)
|
|
}
|
|
}
|
|
|
|
|
|
/* Allocate memory for the firmware image */
|
|
/* Allocate memory for the firmware image */
|
|
- mem_region = dmam_alloc_coherent(dev, mem_size, &mem_phys, GFP_KERNEL);
|
|
|
|
|
|
+ mem_region = memremap(mem_phys, mem_size, MEMREMAP_WC);
|
|
if (!mem_region) {
|
|
if (!mem_region) {
|
|
ret = -ENOMEM;
|
|
ret = -ENOMEM;
|
|
goto out;
|
|
goto out;
|
|
@@ -69,16 +87,13 @@ static int zap_shader_load_mdt(struct device *dev, const char *fwname)
|
|
DRM_DEV_ERROR(dev, "Unable to authorize the image\n");
|
|
DRM_DEV_ERROR(dev, "Unable to authorize the image\n");
|
|
|
|
|
|
out:
|
|
out:
|
|
|
|
+ if (mem_region)
|
|
|
|
+ memunmap(mem_region);
|
|
|
|
+
|
|
release_firmware(fw);
|
|
release_firmware(fw);
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
-#else
|
|
|
|
-static int zap_shader_load_mdt(struct device *dev, const char *fwname)
|
|
|
|
-{
|
|
|
|
- return -ENODEV;
|
|
|
|
-}
|
|
|
|
-#endif
|
|
|
|
|
|
|
|
static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
|
|
static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
|
|
struct msm_file_private *ctx)
|
|
struct msm_file_private *ctx)
|
|
@@ -117,12 +132,10 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
|
|
gpu->funcs->flush(gpu);
|
|
gpu->funcs->flush(gpu);
|
|
}
|
|
}
|
|
|
|
|
|
-struct a5xx_hwcg {
|
|
|
|
|
|
+static const struct {
|
|
u32 offset;
|
|
u32 offset;
|
|
u32 value;
|
|
u32 value;
|
|
-};
|
|
|
|
-
|
|
|
|
-static const struct a5xx_hwcg a530_hwcg[] = {
|
|
|
|
|
|
+} a5xx_hwcg[] = {
|
|
{REG_A5XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
|
|
{REG_A5XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
|
|
{REG_A5XX_RBBM_CLOCK_CNTL_SP1, 0x02222222},
|
|
{REG_A5XX_RBBM_CLOCK_CNTL_SP1, 0x02222222},
|
|
{REG_A5XX_RBBM_CLOCK_CNTL_SP2, 0x02222222},
|
|
{REG_A5XX_RBBM_CLOCK_CNTL_SP2, 0x02222222},
|
|
@@ -217,38 +230,16 @@ static const struct a5xx_hwcg a530_hwcg[] = {
|
|
{REG_A5XX_RBBM_CLOCK_DELAY_VFD, 0x00002222}
|
|
{REG_A5XX_RBBM_CLOCK_DELAY_VFD, 0x00002222}
|
|
};
|
|
};
|
|
|
|
|
|
-static const struct {
|
|
|
|
- int (*test)(struct adreno_gpu *gpu);
|
|
|
|
- const struct a5xx_hwcg *regs;
|
|
|
|
- unsigned int count;
|
|
|
|
-} a5xx_hwcg_regs[] = {
|
|
|
|
- { adreno_is_a530, a530_hwcg, ARRAY_SIZE(a530_hwcg), },
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-static void _a5xx_enable_hwcg(struct msm_gpu *gpu,
|
|
|
|
- const struct a5xx_hwcg *regs, unsigned int count)
|
|
|
|
|
|
+void a5xx_set_hwcg(struct msm_gpu *gpu, bool state)
|
|
{
|
|
{
|
|
unsigned int i;
|
|
unsigned int i;
|
|
|
|
|
|
- for (i = 0; i < count; i++)
|
|
|
|
- gpu_write(gpu, regs[i].offset, regs[i].value);
|
|
|
|
|
|
+ for (i = 0; i < ARRAY_SIZE(a5xx_hwcg); i++)
|
|
|
|
+ gpu_write(gpu, a5xx_hwcg[i].offset,
|
|
|
|
+ state ? a5xx_hwcg[i].value : 0);
|
|
|
|
|
|
- gpu_write(gpu, REG_A5XX_RBBM_CLOCK_CNTL, 0xAAA8AA00);
|
|
|
|
- gpu_write(gpu, REG_A5XX_RBBM_ISDB_CNT, 0x182);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void a5xx_enable_hwcg(struct msm_gpu *gpu)
|
|
|
|
-{
|
|
|
|
- struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
|
|
|
|
- unsigned int i;
|
|
|
|
-
|
|
|
|
- for (i = 0; i < ARRAY_SIZE(a5xx_hwcg_regs); i++) {
|
|
|
|
- if (a5xx_hwcg_regs[i].test(adreno_gpu)) {
|
|
|
|
- _a5xx_enable_hwcg(gpu, a5xx_hwcg_regs[i].regs,
|
|
|
|
- a5xx_hwcg_regs[i].count);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ gpu_write(gpu, REG_A5XX_RBBM_CLOCK_CNTL, state ? 0xAAA8AA00 : 0);
|
|
|
|
+ gpu_write(gpu, REG_A5XX_RBBM_ISDB_CNT, state ? 0x182 : 0x180);
|
|
}
|
|
}
|
|
|
|
|
|
static int a5xx_me_init(struct msm_gpu *gpu)
|
|
static int a5xx_me_init(struct msm_gpu *gpu)
|
|
@@ -377,45 +368,6 @@ static int a5xx_zap_shader_resume(struct msm_gpu *gpu)
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
-/* Set up a child device to "own" the zap shader */
|
|
|
|
-static int a5xx_zap_shader_dev_init(struct device *parent, struct device *dev)
|
|
|
|
-{
|
|
|
|
- struct device_node *node;
|
|
|
|
- int ret;
|
|
|
|
-
|
|
|
|
- if (dev->parent)
|
|
|
|
- return 0;
|
|
|
|
-
|
|
|
|
- /* Find the sub-node for the zap shader */
|
|
|
|
- node = of_get_child_by_name(parent->of_node, "zap-shader");
|
|
|
|
- if (!node) {
|
|
|
|
- DRM_DEV_ERROR(parent, "zap-shader not found in device tree\n");
|
|
|
|
- return -ENODEV;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- dev->parent = parent;
|
|
|
|
- dev->of_node = node;
|
|
|
|
- dev_set_name(dev, "adreno_zap_shader");
|
|
|
|
-
|
|
|
|
- ret = device_register(dev);
|
|
|
|
- if (ret) {
|
|
|
|
- DRM_DEV_ERROR(parent, "Couldn't register zap shader device\n");
|
|
|
|
- goto out;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ret = of_reserved_mem_device_init(dev);
|
|
|
|
- if (ret) {
|
|
|
|
- DRM_DEV_ERROR(parent, "Unable to set up the reserved memory\n");
|
|
|
|
- device_unregister(dev);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-out:
|
|
|
|
- if (ret)
|
|
|
|
- dev->parent = NULL;
|
|
|
|
-
|
|
|
|
- return ret;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static int a5xx_zap_shader_init(struct msm_gpu *gpu)
|
|
static int a5xx_zap_shader_init(struct msm_gpu *gpu)
|
|
{
|
|
{
|
|
static bool loaded;
|
|
static bool loaded;
|
|
@@ -444,11 +396,7 @@ static int a5xx_zap_shader_init(struct msm_gpu *gpu)
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
}
|
|
}
|
|
|
|
|
|
- ret = a5xx_zap_shader_dev_init(&pdev->dev, &a5xx_gpu->zap_dev);
|
|
|
|
-
|
|
|
|
- if (!ret)
|
|
|
|
- ret = zap_shader_load_mdt(&a5xx_gpu->zap_dev,
|
|
|
|
- adreno_gpu->info->zapfw);
|
|
|
|
|
|
+ ret = zap_shader_load_mdt(&pdev->dev, adreno_gpu->info->zapfw);
|
|
|
|
|
|
loaded = !ret;
|
|
loaded = !ret;
|
|
|
|
|
|
@@ -545,7 +493,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
|
|
gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL1, 0xA6FFFFFF);
|
|
gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL1, 0xA6FFFFFF);
|
|
|
|
|
|
/* Enable HWCG */
|
|
/* Enable HWCG */
|
|
- a5xx_enable_hwcg(gpu);
|
|
|
|
|
|
+ a5xx_set_hwcg(gpu, true);
|
|
|
|
|
|
gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F);
|
|
gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F);
|
|
|
|
|
|
@@ -691,9 +639,6 @@ static void a5xx_destroy(struct msm_gpu *gpu)
|
|
|
|
|
|
DBG("%s", gpu->name);
|
|
DBG("%s", gpu->name);
|
|
|
|
|
|
- if (a5xx_gpu->zap_dev.parent)
|
|
|
|
- device_unregister(&a5xx_gpu->zap_dev);
|
|
|
|
-
|
|
|
|
if (a5xx_gpu->pm4_bo) {
|
|
if (a5xx_gpu->pm4_bo) {
|
|
if (a5xx_gpu->pm4_iova)
|
|
if (a5xx_gpu->pm4_iova)
|
|
msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->aspace);
|
|
msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->aspace);
|
|
@@ -920,31 +865,30 @@ static const u32 a5xx_registers[] = {
|
|
0x0000, 0x0002, 0x0004, 0x0020, 0x0022, 0x0026, 0x0029, 0x002B,
|
|
0x0000, 0x0002, 0x0004, 0x0020, 0x0022, 0x0026, 0x0029, 0x002B,
|
|
0x002E, 0x0035, 0x0038, 0x0042, 0x0044, 0x0044, 0x0047, 0x0095,
|
|
0x002E, 0x0035, 0x0038, 0x0042, 0x0044, 0x0044, 0x0047, 0x0095,
|
|
0x0097, 0x00BB, 0x03A0, 0x0464, 0x0469, 0x046F, 0x04D2, 0x04D3,
|
|
0x0097, 0x00BB, 0x03A0, 0x0464, 0x0469, 0x046F, 0x04D2, 0x04D3,
|
|
- 0x04E0, 0x0533, 0x0540, 0x0555, 0xF400, 0xF400, 0xF800, 0xF807,
|
|
|
|
- 0x0800, 0x081A, 0x081F, 0x0841, 0x0860, 0x0860, 0x0880, 0x08A0,
|
|
|
|
- 0x0B00, 0x0B12, 0x0B15, 0x0B28, 0x0B78, 0x0B7F, 0x0BB0, 0x0BBD,
|
|
|
|
- 0x0BC0, 0x0BC6, 0x0BD0, 0x0C53, 0x0C60, 0x0C61, 0x0C80, 0x0C82,
|
|
|
|
- 0x0C84, 0x0C85, 0x0C90, 0x0C98, 0x0CA0, 0x0CA0, 0x0CB0, 0x0CB2,
|
|
|
|
- 0x2180, 0x2185, 0x2580, 0x2585, 0x0CC1, 0x0CC1, 0x0CC4, 0x0CC7,
|
|
|
|
- 0x0CCC, 0x0CCC, 0x0CD0, 0x0CD8, 0x0CE0, 0x0CE5, 0x0CE8, 0x0CE8,
|
|
|
|
- 0x0CEC, 0x0CF1, 0x0CFB, 0x0D0E, 0x2100, 0x211E, 0x2140, 0x2145,
|
|
|
|
- 0x2500, 0x251E, 0x2540, 0x2545, 0x0D10, 0x0D17, 0x0D20, 0x0D23,
|
|
|
|
- 0x0D30, 0x0D30, 0x20C0, 0x20C0, 0x24C0, 0x24C0, 0x0E40, 0x0E43,
|
|
|
|
- 0x0E4A, 0x0E4A, 0x0E50, 0x0E57, 0x0E60, 0x0E7C, 0x0E80, 0x0E8E,
|
|
|
|
- 0x0E90, 0x0E96, 0x0EA0, 0x0EA8, 0x0EB0, 0x0EB2, 0xE140, 0xE147,
|
|
|
|
- 0xE150, 0xE187, 0xE1A0, 0xE1A9, 0xE1B0, 0xE1B6, 0xE1C0, 0xE1C7,
|
|
|
|
- 0xE1D0, 0xE1D1, 0xE200, 0xE201, 0xE210, 0xE21C, 0xE240, 0xE268,
|
|
|
|
- 0xE000, 0xE006, 0xE010, 0xE09A, 0xE0A0, 0xE0A4, 0xE0AA, 0xE0EB,
|
|
|
|
- 0xE100, 0xE105, 0xE380, 0xE38F, 0xE3B0, 0xE3B0, 0xE400, 0xE405,
|
|
|
|
- 0xE408, 0xE4E9, 0xE4F0, 0xE4F0, 0xE280, 0xE280, 0xE282, 0xE2A3,
|
|
|
|
- 0xE2A5, 0xE2C2, 0xE940, 0xE947, 0xE950, 0xE987, 0xE9A0, 0xE9A9,
|
|
|
|
- 0xE9B0, 0xE9B6, 0xE9C0, 0xE9C7, 0xE9D0, 0xE9D1, 0xEA00, 0xEA01,
|
|
|
|
- 0xEA10, 0xEA1C, 0xEA40, 0xEA68, 0xE800, 0xE806, 0xE810, 0xE89A,
|
|
|
|
- 0xE8A0, 0xE8A4, 0xE8AA, 0xE8EB, 0xE900, 0xE905, 0xEB80, 0xEB8F,
|
|
|
|
- 0xEBB0, 0xEBB0, 0xEC00, 0xEC05, 0xEC08, 0xECE9, 0xECF0, 0xECF0,
|
|
|
|
- 0xEA80, 0xEA80, 0xEA82, 0xEAA3, 0xEAA5, 0xEAC2, 0xA800, 0xA8FF,
|
|
|
|
- 0xAC60, 0xAC60, 0xB000, 0xB97F, 0xB9A0, 0xB9BF,
|
|
|
|
- ~0
|
|
|
|
|
|
+ 0x04E0, 0x0533, 0x0540, 0x0555, 0x0800, 0x081A, 0x081F, 0x0841,
|
|
|
|
+ 0x0860, 0x0860, 0x0880, 0x08A0, 0x0B00, 0x0B12, 0x0B15, 0x0B28,
|
|
|
|
+ 0x0B78, 0x0B7F, 0x0BB0, 0x0BBD, 0x0BC0, 0x0BC6, 0x0BD0, 0x0C53,
|
|
|
|
+ 0x0C60, 0x0C61, 0x0C80, 0x0C82, 0x0C84, 0x0C85, 0x0C90, 0x0C98,
|
|
|
|
+ 0x0CA0, 0x0CA0, 0x0CB0, 0x0CB2, 0x2180, 0x2185, 0x2580, 0x2585,
|
|
|
|
+ 0x0CC1, 0x0CC1, 0x0CC4, 0x0CC7, 0x0CCC, 0x0CCC, 0x0CD0, 0x0CD8,
|
|
|
|
+ 0x0CE0, 0x0CE5, 0x0CE8, 0x0CE8, 0x0CEC, 0x0CF1, 0x0CFB, 0x0D0E,
|
|
|
|
+ 0x2100, 0x211E, 0x2140, 0x2145, 0x2500, 0x251E, 0x2540, 0x2545,
|
|
|
|
+ 0x0D10, 0x0D17, 0x0D20, 0x0D23, 0x0D30, 0x0D30, 0x20C0, 0x20C0,
|
|
|
|
+ 0x24C0, 0x24C0, 0x0E40, 0x0E43, 0x0E4A, 0x0E4A, 0x0E50, 0x0E57,
|
|
|
|
+ 0x0E60, 0x0E7C, 0x0E80, 0x0E8E, 0x0E90, 0x0E96, 0x0EA0, 0x0EA8,
|
|
|
|
+ 0x0EB0, 0x0EB2, 0xE140, 0xE147, 0xE150, 0xE187, 0xE1A0, 0xE1A9,
|
|
|
|
+ 0xE1B0, 0xE1B6, 0xE1C0, 0xE1C7, 0xE1D0, 0xE1D1, 0xE200, 0xE201,
|
|
|
|
+ 0xE210, 0xE21C, 0xE240, 0xE268, 0xE000, 0xE006, 0xE010, 0xE09A,
|
|
|
|
+ 0xE0A0, 0xE0A4, 0xE0AA, 0xE0EB, 0xE100, 0xE105, 0xE380, 0xE38F,
|
|
|
|
+ 0xE3B0, 0xE3B0, 0xE400, 0xE405, 0xE408, 0xE4E9, 0xE4F0, 0xE4F0,
|
|
|
|
+ 0xE280, 0xE280, 0xE282, 0xE2A3, 0xE2A5, 0xE2C2, 0xE940, 0xE947,
|
|
|
|
+ 0xE950, 0xE987, 0xE9A0, 0xE9A9, 0xE9B0, 0xE9B6, 0xE9C0, 0xE9C7,
|
|
|
|
+ 0xE9D0, 0xE9D1, 0xEA00, 0xEA01, 0xEA10, 0xEA1C, 0xEA40, 0xEA68,
|
|
|
|
+ 0xE800, 0xE806, 0xE810, 0xE89A, 0xE8A0, 0xE8A4, 0xE8AA, 0xE8EB,
|
|
|
|
+ 0xE900, 0xE905, 0xEB80, 0xEB8F, 0xEBB0, 0xEBB0, 0xEC00, 0xEC05,
|
|
|
|
+ 0xEC08, 0xECE9, 0xECF0, 0xECF0, 0xEA80, 0xEA80, 0xEA82, 0xEAA3,
|
|
|
|
+ 0xEAA5, 0xEAC2, 0xA800, 0xA8FF, 0xAC60, 0xAC60, 0xB000, 0xB97F,
|
|
|
|
+ 0xB9A0, 0xB9BF, ~0
|
|
};
|
|
};
|
|
|
|
|
|
static void a5xx_dump(struct msm_gpu *gpu)
|
|
static void a5xx_dump(struct msm_gpu *gpu)
|
|
@@ -1020,7 +964,14 @@ static void a5xx_show(struct msm_gpu *gpu, struct seq_file *m)
|
|
{
|
|
{
|
|
seq_printf(m, "status: %08x\n",
|
|
seq_printf(m, "status: %08x\n",
|
|
gpu_read(gpu, REG_A5XX_RBBM_STATUS));
|
|
gpu_read(gpu, REG_A5XX_RBBM_STATUS));
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Temporarily disable hardware clock gating before going into
|
|
|
|
+ * adreno_show to avoid issues while reading the registers
|
|
|
|
+ */
|
|
|
|
+ a5xx_set_hwcg(gpu, false);
|
|
adreno_show(gpu, m);
|
|
adreno_show(gpu, m);
|
|
|
|
+ a5xx_set_hwcg(gpu, true);
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|