1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Copyright (C) 2020 Unisoc Inc. |
4 | */ |
5 | |
6 | #ifndef __SPRD_DPU_H__ |
7 | #define __SPRD_DPU_H__ |
8 | |
9 | #include <linux/bug.h> |
10 | #include <linux/delay.h> |
11 | #include <linux/device.h> |
12 | #include <linux/kernel.h> |
13 | #include <linux/platform_device.h> |
14 | #include <linux/string.h> |
15 | #include <video/videomode.h> |
16 | |
17 | #include <drm/drm_crtc.h> |
18 | #include <drm/drm_fourcc.h> |
19 | #include <drm/drm_print.h> |
20 | #include <drm/drm_vblank.h> |
21 | #include <uapi/drm/drm_mode.h> |
22 | |
23 | /* DPU Layer registers offset */ |
24 | #define DPU_LAY_REG_OFFSET 0x30 |
25 | |
26 | enum { |
27 | SPRD_DPU_IF_DPI, |
28 | SPRD_DPU_IF_EDPI, |
29 | SPRD_DPU_IF_LIMIT |
30 | }; |
31 | |
32 | /** |
33 | * Sprd DPU context structure |
34 | * |
35 | * @base: DPU controller base address |
36 | * @irq: IRQ number to install the handler for |
37 | * @if_type: The type of DPI interface, default is DPI mode. |
38 | * @vm: videomode structure to use for DPU and DPI initialization |
39 | * @stopped: indicates whether DPU are stopped |
40 | * @wait_queue: wait queue, used to wait for DPU shadow register update done and |
41 | * DPU stop register done interrupt signal. |
42 | * @evt_update: wait queue condition for DPU shadow register |
43 | * @evt_stop: wait queue condition for DPU stop register |
44 | */ |
45 | struct dpu_context { |
46 | void __iomem *base; |
47 | int irq; |
48 | u8 if_type; |
49 | struct videomode vm; |
50 | bool stopped; |
51 | wait_queue_head_t wait_queue; |
52 | bool evt_update; |
53 | bool evt_stop; |
54 | }; |
55 | |
56 | /** |
57 | * Sprd DPU device structure |
58 | * |
59 | * @crtc: crtc object |
60 | * @drm: A point to drm device |
61 | * @ctx: DPU's implementation specific context object |
62 | */ |
63 | struct sprd_dpu { |
64 | struct drm_crtc base; |
65 | struct drm_device *drm; |
66 | struct dpu_context ctx; |
67 | }; |
68 | |
69 | static inline struct sprd_dpu *to_sprd_crtc(struct drm_crtc *crtc) |
70 | { |
71 | return container_of(crtc, struct sprd_dpu, base); |
72 | } |
73 | |
74 | static inline void |
75 | dpu_reg_set(struct dpu_context *ctx, u32 offset, u32 set_bits) |
76 | { |
77 | u32 bits = readl_relaxed(ctx->base + offset); |
78 | |
79 | writel(val: bits | set_bits, addr: ctx->base + offset); |
80 | } |
81 | |
82 | static inline void |
83 | dpu_reg_clr(struct dpu_context *ctx, u32 offset, u32 clr_bits) |
84 | { |
85 | u32 bits = readl_relaxed(ctx->base + offset); |
86 | |
87 | writel(val: bits & ~clr_bits, addr: ctx->base + offset); |
88 | } |
89 | |
90 | static inline u32 |
91 | layer_reg_rd(struct dpu_context *ctx, u32 offset, int index) |
92 | { |
93 | u32 layer_offset = offset + index * DPU_LAY_REG_OFFSET; |
94 | |
95 | return readl(addr: ctx->base + layer_offset); |
96 | } |
97 | |
98 | static inline void |
99 | layer_reg_wr(struct dpu_context *ctx, u32 offset, u32 cfg_bits, int index) |
100 | { |
101 | u32 layer_offset = offset + index * DPU_LAY_REG_OFFSET; |
102 | |
103 | writel(val: cfg_bits, addr: ctx->base + layer_offset); |
104 | } |
105 | |
106 | void sprd_dpu_run(struct sprd_dpu *dpu); |
107 | void sprd_dpu_stop(struct sprd_dpu *dpu); |
108 | |
109 | #endif |
110 | |