build/patch/kernel/sunxi-next/0078-drm-lima-user-can-choose-not-to-use-dlbu-on-mali450.patch

309 lines
9.6 KiB
Diff

From ed6a8088a598439e2cd5d1ab86389b658f19e465 Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Wed, 15 Aug 2018 11:17:09 +0800
Subject: [PATCH 078/146] drm/lima: user can choose not to use dlbu on mali450
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_bcast.c | 24 +++++-----
drivers/gpu/drm/lima/lima_bcast.h | 3 +-
drivers/gpu/drm/lima/lima_device.c | 5 --
drivers/gpu/drm/lima/lima_dlbu.c | 4 +-
drivers/gpu/drm/lima/lima_dlbu.h | 2 +-
drivers/gpu/drm/lima/lima_pp.c | 75 ++++++++++++++++++------------
include/uapi/drm/lima_drm.h | 9 +++-
7 files changed, 67 insertions(+), 55 deletions(-)
diff --git a/drivers/gpu/drm/lima/lima_bcast.c b/drivers/gpu/drm/lima/lima_bcast.c
index 6c2004dce648..63754f6465ea 100644
--- a/drivers/gpu/drm/lima/lima_bcast.c
+++ b/drivers/gpu/drm/lima/lima_bcast.c
@@ -11,31 +11,31 @@
#define bcast_write(reg, data) writel(data, ip->iomem + LIMA_BCAST_##reg)
#define bcast_read(reg) readl(ip->iomem + LIMA_BCAST_##reg)
-void lima_bcast_enable(struct lima_device *dev)
+void lima_bcast_enable(struct lima_device *dev, int num_pp)
{
struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
struct lima_ip *ip = dev->ip + lima_ip_bcast;
- int i, mask = 0;
+ int i, mask = bcast_read(BROADCAST_MASK) & 0xffff0000;
- for (i = 0; i < pipe->num_processor; i++) {
+ for (i = 0; i < num_pp; i++) {
struct lima_ip *pp = pipe->processor[i];
mask |= 1 << (pp->id - lima_ip_pp0);
}
- bcast_write(BROADCAST_MASK, (mask << 16) | mask);
- bcast_write(INTERRUPT_MASK, mask);
+ bcast_write(BROADCAST_MASK, mask);
}
-void lima_bcast_disable(struct lima_device *dev)
+int lima_bcast_init(struct lima_ip *ip)
{
- struct lima_ip *ip = dev->ip + lima_ip_bcast;
+ int i, mask = 0;
- bcast_write(BROADCAST_MASK, 0);
- bcast_write(INTERRUPT_MASK, 0);
-}
+ for (i = lima_ip_pp0; i <= lima_ip_pp7; i++) {
+ if (ip->dev->ip[i].present)
+ mask |= 1 << (i - lima_ip_pp0);
+ }
-int lima_bcast_init(struct lima_ip *ip)
-{
+ bcast_write(BROADCAST_MASK, mask << 16);
+ bcast_write(INTERRUPT_MASK, mask);
return 0;
}
diff --git a/drivers/gpu/drm/lima/lima_bcast.h b/drivers/gpu/drm/lima/lima_bcast.h
index fb8e1f318c5c..345e3e809860 100644
--- a/drivers/gpu/drm/lima/lima_bcast.h
+++ b/drivers/gpu/drm/lima/lima_bcast.h
@@ -9,7 +9,6 @@ struct lima_ip;
int lima_bcast_init(struct lima_ip *ip);
void lima_bcast_fini(struct lima_ip *ip);
-void lima_bcast_enable(struct lima_device *dev);
-void lima_bcast_disable(struct lima_device *dev);
+void lima_bcast_enable(struct lima_device *dev, int num_pp);
#endif
diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c
index c85196af8830..b88c84d796fc 100644
--- a/drivers/gpu/drm/lima/lima_device.c
+++ b/drivers/gpu/drm/lima/lima_device.c
@@ -338,11 +338,6 @@ int lima_device_init(struct lima_device *ldev)
if (err)
goto err_out6;
- if (ldev->id == lima_gpu_mali450) {
- lima_dlbu_enable(ldev);
- lima_bcast_enable(ldev);
- }
-
return 0;
err_out6:
diff --git a/drivers/gpu/drm/lima/lima_dlbu.c b/drivers/gpu/drm/lima/lima_dlbu.c
index 444a74348d5e..6697d4ddd887 100644
--- a/drivers/gpu/drm/lima/lima_dlbu.c
+++ b/drivers/gpu/drm/lima/lima_dlbu.c
@@ -12,13 +12,13 @@
#define dlbu_write(reg, data) writel(data, ip->iomem + LIMA_DLBU_##reg)
#define dlbu_read(reg) readl(ip->iomem + LIMA_DLBU_##reg)
-void lima_dlbu_enable(struct lima_device *dev)
+void lima_dlbu_enable(struct lima_device *dev, int num_pp)
{
struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
struct lima_ip *ip = dev->ip + lima_ip_dlbu;
int i, mask = 0;
- for (i = 0; i < pipe->num_processor; i++) {
+ for (i = 0; i < num_pp; i++) {
struct lima_ip *pp = pipe->processor[i];
mask |= 1 << (pp->id - lima_ip_pp0);
}
diff --git a/drivers/gpu/drm/lima/lima_dlbu.h b/drivers/gpu/drm/lima/lima_dlbu.h
index 6d85403fa410..60cba387cf30 100644
--- a/drivers/gpu/drm/lima/lima_dlbu.h
+++ b/drivers/gpu/drm/lima/lima_dlbu.h
@@ -7,7 +7,7 @@
struct lima_ip;
struct lima_device;
-void lima_dlbu_enable(struct lima_device *dev);
+void lima_dlbu_enable(struct lima_device *dev, int num_pp);
void lima_dlbu_disable(struct lima_device *dev);
void lima_dlbu_set_reg(struct lima_ip *ip, u32 *reg);
diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c
index 29e3ddfb394b..3355895ceeba 100644
--- a/drivers/gpu/drm/lima/lima_pp.c
+++ b/drivers/gpu/drm/lima/lima_pp.c
@@ -64,8 +64,9 @@ static irqreturn_t lima_pp_bcast_irq_handler(int irq, void *data)
struct lima_ip *pp_bcast = data;
struct lima_device *dev = pp_bcast->dev;
struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+ struct drm_lima_m450_pp_frame *frame = pipe->current_task->frame;
- for (i = 0; i < pipe->num_processor; i++) {
+ for (i = 0; i < frame->num_pp; i++) {
struct lima_ip *ip = pipe->processor[i];
u32 status, state;
@@ -135,7 +136,9 @@ static int lima_pp_soft_reset_async_wait(struct lima_ip *ip)
if (ip->id == lima_ip_pp_bcast) {
struct lima_device *dev = ip->dev;
struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
- for (i = 0; i < pipe->num_processor; i++)
+ struct drm_lima_m450_pp_frame *frame = pipe->current_task->frame;
+
+ for (i = 0; i < frame->num_pp; i++)
err |= lima_pp_soft_reset_async_wait_one(pipe->processor[i]);
}
else
@@ -145,24 +148,17 @@ static int lima_pp_soft_reset_async_wait(struct lima_ip *ip)
return err;
}
-static void lima_pp_start_task(struct lima_ip *ip, u32 *frame, u32 *wb,
- bool skip_stack_addr)
+static void lima_pp_write_frame(struct lima_ip *ip, u32 *frame, u32 *wb)
{
int i, j, n = 0;
- for (i = 0; i < LIMA_PP_FRAME_REG_NUM; i++) {
- if (skip_stack_addr && i * 4 == LIMA_PP_STACK)
- continue;
-
+ for (i = 0; i < LIMA_PP_FRAME_REG_NUM; i++)
writel(frame[i], ip->iomem + LIMA_PP_FRAME + i * 4);
- }
for (i = 0; i < 3; i++) {
for (j = 0; j < LIMA_PP_WB_REG_NUM; j++)
writel(wb[n++], ip->iomem + LIMA_PP_WB(i) + j * 4);
}
-
- pp_write(CTRL, LIMA_PP_CTRL_START_RENDERING);
}
static int lima_pp_hard_reset(struct lima_ip *ip)
@@ -271,13 +267,20 @@ void lima_pp_bcast_fini(struct lima_ip *ip)
static int lima_pp_task_validate(struct lima_sched_pipe *pipe,
struct lima_sched_task *task)
{
- if (!pipe->bcast_processor) {
- struct drm_lima_m400_pp_frame *f = task->frame;
+ u32 num_pp;
- if (f->num_pp > pipe->num_processor)
- return -EINVAL;
+ if (pipe->bcast_processor) {
+ struct drm_lima_m450_pp_frame *f = task->frame;
+ num_pp = f->num_pp;
+ }
+ else {
+ struct drm_lima_m400_pp_frame *f = task->frame;
+ num_pp = f->num_pp;
}
+ if (num_pp == 0 || num_pp > pipe->num_processor)
+ return -EINVAL;
+
return 0;
}
@@ -287,23 +290,36 @@ static void lima_pp_task_run(struct lima_sched_pipe *pipe,
if (pipe->bcast_processor) {
struct drm_lima_m450_pp_frame *frame = task->frame;
struct lima_device *dev = pipe->bcast_processor->dev;
+ struct lima_ip *ip = pipe->bcast_processor;
int i;
pipe->done = 0;
- atomic_set(&pipe->task, pipe->num_processor);
+ atomic_set(&pipe->task, frame->num_pp);
- frame->frame[LIMA_PP_FRAME >> 2] = LIMA_VA_RESERVE_DLBU;
- lima_dlbu_set_reg(dev->ip + lima_ip_dlbu, frame->dlbu_regs);
+ if (frame->use_dlbu) {
+ lima_dlbu_enable(dev, frame->num_pp);
- lima_pp_soft_reset_async_wait(pipe->bcast_processor);
+ frame->frame[LIMA_PP_FRAME >> 2] = LIMA_VA_RESERVE_DLBU;
+ lima_dlbu_set_reg(dev->ip + lima_ip_dlbu, frame->dlbu_regs);
+ }
+ else
+ lima_dlbu_disable(dev);
+
+ lima_bcast_enable(dev, frame->num_pp);
+
+ lima_pp_soft_reset_async_wait(ip);
+
+ lima_pp_write_frame(ip, frame->frame, frame->wb);
- for (i = 0; i < pipe->num_processor; i++) {
+ for (i = 0; i < frame->num_pp; i++) {
struct lima_ip *ip = pipe->processor[i];
+
pp_write(STACK, frame->fragment_stack_address[i]);
+ if (!frame->use_dlbu)
+ pp_write(FRAME, frame->plbu_array_address[i]);
}
- lima_pp_start_task(pipe->bcast_processor, frame->frame,
- frame->wb, true);
+ pp_write(CTRL, LIMA_PP_CTRL_START_RENDERING);
}
else {
struct drm_lima_m400_pp_frame *frame = task->frame;
@@ -312,15 +328,18 @@ static void lima_pp_task_run(struct lima_sched_pipe *pipe,
atomic_set(&pipe->task, frame->num_pp);
for (i = 0; i < frame->num_pp; i++) {
+ struct lima_ip *ip = pipe->processor[i];
+
frame->frame[LIMA_PP_FRAME >> 2] =
frame->plbu_array_address[i];
frame->frame[LIMA_PP_STACK >> 2] =
frame->fragment_stack_address[i];
- lima_pp_soft_reset_async_wait(pipe->processor[i]);
+ lima_pp_soft_reset_async_wait(ip);
+
+ lima_pp_write_frame(ip, frame->frame, frame->wb);
- lima_pp_start_task(pipe->processor[i], frame->frame,
- frame->wb, false);
+ pp_write(CTRL, LIMA_PP_CTRL_START_RENDERING);
}
}
}
@@ -340,14 +359,8 @@ static void lima_pp_task_error(struct lima_sched_pipe *pipe)
{
int i;
- if (pipe->bcast_processor)
- lima_bcast_disable(pipe->bcast_processor->dev);
-
for (i = 0; i < pipe->num_processor; i++)
lima_pp_hard_reset(pipe->processor[i]);
-
- if (pipe->bcast_processor)
- lima_bcast_enable(pipe->bcast_processor->dev);
}
static void lima_pp_task_mmu_error(struct lima_sched_pipe *pipe)
diff --git a/include/uapi/drm/lima_drm.h b/include/uapi/drm/lima_drm.h
index 77cb39af1a45..0c17bf693184 100644
--- a/include/uapi/drm/lima_drm.h
+++ b/include/uapi/drm/lima_drm.h
@@ -91,9 +91,14 @@ struct drm_lima_m400_pp_frame {
struct drm_lima_m450_pp_frame {
__u32 frame[LIMA_PP_FRAME_REG_NUM];
- __u32 _pad;
+ __u32 num_pp;
__u32 wb[3 * LIMA_PP_WB_REG_NUM];
- __u32 dlbu_regs[4];
+ __u32 use_dlbu;
+ __u32 _pad;
+ union {
+ __u32 plbu_array_address[8];
+ __u32 dlbu_regs[4];
+ };
__u32 fragment_stack_address[8];
};
--
2.17.1