mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
Adds DPU(Display Processor Unit) support for the Unisoc's display
subsystem.
It's support multi planes, scaler, rotation, PQ(Picture Quality) and more.
v2:
- Use drm_xxx to replace all DRM_XXX.
- Use kzalloc to replace devm_kzalloc for sprd_dpu structure init.
v3:
- Remove dpu_layer stuff layer and commit layers by aotmic_update
v4:
- Use drmm_helpers to allocate crtc and planes.
- Move rotation enum definitions to crtc layer reg bitfields.
- Move allocate crtc and planes to bind function.
v5:
- Fix the checkpatch warnings.
- Use mode_set_nofb instead of mode_valid callback.
- Follow the OF-Graph bindings, use of_graph_get_port_by_id
instead of of_parse_phandle.
- Use zpos to represent the layer position.
- Rebase to last drm misc branch.
v6:
- Disable and clear interrupts before register dpu IRQ
- Init dpi config used by crtc_state->adjusted_mode on mode_set_nofb
- Remove enable_irq and disable_irq function call.
- Remove drm_format_info function call.
v7:
- Remove iommu error interrupt handling function.
Cc: Orson Zhai <orsonzhai@gmail.com>
Cc: Chunyan Zhang <zhang.lyra@gmail.com>
Signed-off-by: Kevin Tang <kevin.tang@unisoc.com>
Reviewed-by: Maxime Ripard <maxime@cerno.tech>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211207142717.30296-5-kevin3.tang@gmail.com
110 lines
2.5 KiB
C
110 lines
2.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (C) 2020 Unisoc Inc.
|
|
*/
|
|
|
|
#ifndef __SPRD_DPU_H__
|
|
#define __SPRD_DPU_H__
|
|
|
|
#include <linux/bug.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/device.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/string.h>
|
|
#include <video/videomode.h>
|
|
|
|
#include <drm/drm_crtc.h>
|
|
#include <drm/drm_fourcc.h>
|
|
#include <drm/drm_print.h>
|
|
#include <drm/drm_vblank.h>
|
|
#include <uapi/drm/drm_mode.h>
|
|
|
|
/* DPU Layer registers offset */
|
|
#define DPU_LAY_REG_OFFSET 0x30
|
|
|
|
enum {
|
|
SPRD_DPU_IF_DPI,
|
|
SPRD_DPU_IF_EDPI,
|
|
SPRD_DPU_IF_LIMIT
|
|
};
|
|
|
|
/**
|
|
* Sprd DPU context structure
|
|
*
|
|
* @base: DPU controller base address
|
|
* @irq: IRQ number to install the handler for
|
|
* @if_type: The type of DPI interface, default is DPI mode.
|
|
* @vm: videomode structure to use for DPU and DPI initialization
|
|
* @stopped: indicates whether DPU are stopped
|
|
* @wait_queue: wait queue, used to wait for DPU shadow register update done and
|
|
* DPU stop register done interrupt signal.
|
|
* @evt_update: wait queue condition for DPU shadow register
|
|
* @evt_stop: wait queue condition for DPU stop register
|
|
*/
|
|
struct dpu_context {
|
|
void __iomem *base;
|
|
int irq;
|
|
u8 if_type;
|
|
struct videomode vm;
|
|
bool stopped;
|
|
wait_queue_head_t wait_queue;
|
|
bool evt_update;
|
|
bool evt_stop;
|
|
};
|
|
|
|
/**
|
|
* Sprd DPU device structure
|
|
*
|
|
* @crtc: crtc object
|
|
* @drm: A point to drm device
|
|
* @ctx: DPU's implementation specific context object
|
|
*/
|
|
struct sprd_dpu {
|
|
struct drm_crtc base;
|
|
struct drm_device *drm;
|
|
struct dpu_context ctx;
|
|
};
|
|
|
|
static inline struct sprd_dpu *to_sprd_crtc(struct drm_crtc *crtc)
|
|
{
|
|
return container_of(crtc, struct sprd_dpu, base);
|
|
}
|
|
|
|
static inline void
|
|
dpu_reg_set(struct dpu_context *ctx, u32 offset, u32 set_bits)
|
|
{
|
|
u32 bits = readl_relaxed(ctx->base + offset);
|
|
|
|
writel(bits | set_bits, ctx->base + offset);
|
|
}
|
|
|
|
static inline void
|
|
dpu_reg_clr(struct dpu_context *ctx, u32 offset, u32 clr_bits)
|
|
{
|
|
u32 bits = readl_relaxed(ctx->base + offset);
|
|
|
|
writel(bits & ~clr_bits, ctx->base + offset);
|
|
}
|
|
|
|
static inline u32
|
|
layer_reg_rd(struct dpu_context *ctx, u32 offset, int index)
|
|
{
|
|
u32 layer_offset = offset + index * DPU_LAY_REG_OFFSET;
|
|
|
|
return readl(ctx->base + layer_offset);
|
|
}
|
|
|
|
static inline void
|
|
layer_reg_wr(struct dpu_context *ctx, u32 offset, u32 cfg_bits, int index)
|
|
{
|
|
u32 layer_offset = offset + index * DPU_LAY_REG_OFFSET;
|
|
|
|
writel(cfg_bits, ctx->base + layer_offset);
|
|
}
|
|
|
|
void sprd_dpu_run(struct sprd_dpu *dpu);
|
|
void sprd_dpu_stop(struct sprd_dpu *dpu);
|
|
|
|
#endif
|