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
|