From ed6a8088a598439e2cd5d1ab86389b658f19e465 Mon Sep 17 00:00:00 2001 From: Qiang Yu 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 --- 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