Commit b5f103ab authored by Jordan Crouse's avatar Jordan Crouse Committed by Rob Clark

drm/msm: gpu: Add A5XX target support

Add support for the A5XX family of Adreno GPUs.
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent 4ac277cd
......@@ -6,6 +6,7 @@ msm-y := \
adreno/adreno_gpu.o \
adreno/a3xx_gpu.o \
adreno/a4xx_gpu.o \
adreno/a5xx_gpu.o \
hdmi/hdmi.o \
hdmi/hdmi_audio.o \
hdmi/hdmi_bridge.o \
......
This diff is collapsed.
/* Copyright (c) 2016 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
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __A5XX_GPU_H__
#define __A5XX_GPU_H__
#include "adreno_gpu.h"
/* Bringing over the hack from the previous targets */
#undef ROP_COPY
#undef ROP_XOR
#include "a5xx.xml.h"
struct a5xx_gpu {
struct adreno_gpu base;
struct platform_device *pdev;
struct drm_gem_object *pm4_bo;
uint64_t pm4_iova;
struct drm_gem_object *pfp_bo;
uint64_t pfp_iova;
};
#define to_a5xx_gpu(x) container_of(x, struct a5xx_gpu, base)
#endif /* __A5XX_GPU_H__ */
......@@ -74,6 +74,14 @@ static const struct adreno_info gpulist[] = {
.pfpfw = "a420_pfp.fw",
.gmem = (SZ_1M + SZ_512K),
.init = a4xx_gpu_init,
}, {
.rev = ADRENO_REV(5, 3, 0, ANY_ID),
.revn = 530,
.name = "A530",
.pm4fw = "a530_pm4.fw",
.pfpfw = "a530_pfp.fw",
.gmem = SZ_1M,
.init = a5xx_gpu_init,
},
};
......@@ -83,6 +91,8 @@ MODULE_FIRMWARE("a330_pm4.fw");
MODULE_FIRMWARE("a330_pfp.fw");
MODULE_FIRMWARE("a420_pm4.fw");
MODULE_FIRMWARE("a420_pfp.fw");
MODULE_FIRMWARE("a530_fm4.fw");
MODULE_FIRMWARE("a530_pfp.fw");
static inline bool _rev_match(uint8_t entry, uint8_t id)
{
......@@ -170,12 +180,20 @@ static void set_gpu_pdev(struct drm_device *dev,
priv->gpu_pdev = pdev;
}
static const struct {
const char *str;
uint32_t flag;
} quirks[] = {
{ "qcom,gpu-quirk-two-pass-use-wfi", ADRENO_QUIRK_TWO_PASS_USE_WFI },
{ "qcom,gpu-quirk-fault-detect-mask", ADRENO_QUIRK_FAULT_DETECT_MASK },
};
static int adreno_bind(struct device *dev, struct device *master, void *data)
{
static struct adreno_platform_config config = {};
struct device_node *child, *node = dev->of_node;
u32 val;
int ret;
int ret, i;
ret = of_property_read_u32(node, "qcom,chipid", &val);
if (ret) {
......@@ -209,6 +227,10 @@ static int adreno_bind(struct device *dev, struct device *master, void *data)
return -ENXIO;
}
for (i = 0; i < ARRAY_SIZE(quirks); i++)
if (of_property_read_bool(node, quirks[i].str))
config.quirks |= quirks[i].flag;
dev->platform_data = &config;
set_gpu_pdev(dev_get_drvdata(master), to_platform_device(dev));
return 0;
......
......@@ -22,7 +22,7 @@
#include "msm_mmu.h"
#define RB_SIZE SZ_32K
#define RB_BLKSIZE 16
#define RB_BLKSIZE 32
int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value)
{
......@@ -54,9 +54,6 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value)
}
}
#define rbmemptr(adreno_gpu, member) \
((adreno_gpu)->memptrs_iova + offsetof(struct adreno_rbmemptrs, member))
int adreno_hw_init(struct msm_gpu *gpu)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
......@@ -349,6 +346,7 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
adreno_gpu->gmem = adreno_gpu->info->gmem;
adreno_gpu->revn = adreno_gpu->info->revn;
adreno_gpu->rev = config->rev;
adreno_gpu->quirks = config->quirks;
gpu->fast_rate = config->fast_rate;
gpu->slow_rate = config->slow_rate;
......
......@@ -48,6 +48,11 @@ enum adreno_regs {
REG_ADRENO_REGISTER_MAX,
};
enum adreno_quirks {
ADRENO_QUIRK_TWO_PASS_USE_WFI = 1,
ADRENO_QUIRK_FAULT_DETECT_MASK = 2,
};
struct adreno_rev {
uint8_t core;
uint8_t major;
......@@ -74,6 +79,9 @@ struct adreno_info {
const struct adreno_info *adreno_info(struct adreno_rev rev);
#define rbmemptr(adreno_gpu, member) \
((adreno_gpu)->memptrs_iova + offsetof(struct adreno_rbmemptrs, member))
struct adreno_rbmemptrs {
volatile uint32_t rptr;
volatile uint32_t wptr;
......@@ -107,6 +115,8 @@ struct adreno_gpu {
* code (a3xx_gpu.c) and stored in this common location.
*/
const unsigned int *reg_offsets;
uint32_t quirks;
};
#define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base)
......@@ -117,6 +127,7 @@ struct adreno_platform_config {
#ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING
struct msm_bus_scale_pdata *bus_scale_table;
#endif
uint32_t quirks;
};
#define ADRENO_IDLE_TIMEOUT msecs_to_jiffies(1000)
......@@ -180,6 +191,11 @@ static inline int adreno_is_a430(struct adreno_gpu *gpu)
return gpu->revn == 430;
}
static inline int adreno_is_a530(struct adreno_gpu *gpu)
{
return gpu->revn == 530;
}
int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value);
int adreno_hw_init(struct msm_gpu *gpu);
uint32_t adreno_last_fence(struct msm_gpu *gpu);
......@@ -299,6 +315,7 @@ static inline void adreno_gpu_write(struct adreno_gpu *gpu,
struct msm_gpu *a3xx_gpu_init(struct drm_device *dev);
struct msm_gpu *a4xx_gpu_init(struct drm_device *dev);
struct msm_gpu *a5xx_gpu_init(struct drm_device *dev);
static inline void adreno_gpu_write64(struct adreno_gpu *gpu,
enum adreno_regs lo, enum adreno_regs hi, u64 data)
......@@ -307,4 +324,28 @@ static inline void adreno_gpu_write64(struct adreno_gpu *gpu,
adreno_gpu_write(gpu, hi, upper_32_bits(data));
}
/*
* Given a register and a count, return a value to program into
* REG_CP_PROTECT_REG(n) - this will block both reads and writes for _len
* registers starting at _reg.
*
* The register base needs to be a multiple of the length. If it is not, the
* hardware will quietly mask off the bits for you and shift the size. For
* example, if you intend the protection to start at 0x07 for a length of 4
* (0x07-0x0A) the hardware will actually protect (0x04-0x07) which might
* expose registers you intended to protect!
*/
#define ADRENO_PROTECT_RW(_reg, _len) \
((1 << 30) | (1 << 29) | \
((ilog2((_len)) & 0x1F) << 24) | (((_reg) << 2) & 0xFFFFF))
/*
* Same as above, but allow reads over the range. For areas of mixed use (such
* as performance counters) this allows us to protect a much larger range with a
* single register
*/
#define ADRENO_PROTECT_RDONLY(_reg, _len) \
((1 << 29) \
((ilog2((_len)) & 0x1F) << 24) | (((_reg) << 2) & 0xFFFFF))
#endif /* __ADRENO_GPU_H__ */
......@@ -96,6 +96,10 @@ static int enable_clk(struct msm_gpu *gpu)
if (gpu->grp_clks[0] && gpu->fast_rate)
clk_set_rate(gpu->grp_clks[0], gpu->fast_rate);
/* Set the RBBM timer rate to 19.2Mhz */
if (gpu->grp_clks[2])
clk_set_rate(gpu->grp_clks[2], 19200000);
for (i = ARRAY_SIZE(gpu->grp_clks) - 1; i >= 0; i--)
if (gpu->grp_clks[i])
clk_prepare(gpu->grp_clks[i]);
......@@ -122,6 +126,9 @@ static int disable_clk(struct msm_gpu *gpu)
if (gpu->grp_clks[0] && gpu->slow_rate)
clk_set_rate(gpu->grp_clks[0], gpu->slow_rate);
if (gpu->grp_clks[2])
clk_set_rate(gpu->grp_clks[2], 0);
return 0;
}
......@@ -553,8 +560,8 @@ static irqreturn_t irq_handler(int irq, void *data)
}
static const char *clk_names[] = {
"core_clk", "iface_clk", "mem_clk", "mem_iface_clk",
"alt_mem_iface_clk",
"core_clk", "iface_clk", "rbbmtimer_clk", "mem_clk",
"mem_iface_clk", "alt_mem_iface_clk",
};
int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
......@@ -647,7 +654,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
iommu = iommu_domain_alloc(&platform_bus_type);
if (iommu) {
/* TODO 32b vs 64b address space.. */
iommu->geometry.aperture_start = 0x1000;
iommu->geometry.aperture_start = SZ_16M;
iommu->geometry.aperture_end = 0xffffffff;
dev_info(drm->dev, "%s: using IOMMU\n", name);
......
......@@ -103,7 +103,7 @@ struct msm_gpu {
/* Power Control: */
struct regulator *gpu_reg, *gpu_cx;
struct clk *ebi1_clk, *grp_clks[5];
struct clk *ebi1_clk, *grp_clks[6];
uint32_t fast_rate, slow_rate, bus_freq;
#ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment