1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * Copyright (C) 2013 Red Hat |
4 | * Author: Rob Clark <robdclark@gmail.com> |
5 | */ |
6 | |
7 | #ifndef __MDP_KMS_H__ |
8 | #define __MDP_KMS_H__ |
9 | |
10 | #include <linux/clk.h> |
11 | #include <linux/platform_device.h> |
12 | #include <linux/regulator/consumer.h> |
13 | |
14 | #include "msm_drv.h" |
15 | #include "msm_kms.h" |
16 | #include "mdp_common.xml.h" |
17 | |
18 | struct mdp_kms; |
19 | |
20 | struct mdp_kms_funcs { |
21 | struct msm_kms_funcs base; |
22 | void (*set_irqmask)(struct mdp_kms *mdp_kms, uint32_t irqmask, |
23 | uint32_t old_irqmask); |
24 | }; |
25 | |
26 | struct mdp_kms { |
27 | struct msm_kms base; |
28 | |
29 | const struct mdp_kms_funcs *funcs; |
30 | |
31 | /* irq handling: */ |
32 | bool in_irq; |
33 | struct list_head irq_list; /* list of mdp4_irq */ |
34 | uint32_t vblank_mask; /* irq bits set for userspace vblank */ |
35 | uint32_t cur_irq_mask; /* current irq mask */ |
36 | }; |
37 | #define to_mdp_kms(x) container_of(x, struct mdp_kms, base) |
38 | |
39 | static inline int mdp_kms_init(struct mdp_kms *mdp_kms, |
40 | const struct mdp_kms_funcs *funcs) |
41 | { |
42 | mdp_kms->funcs = funcs; |
43 | INIT_LIST_HEAD(list: &mdp_kms->irq_list); |
44 | return msm_kms_init(&mdp_kms->base, &funcs->base); |
45 | } |
46 | |
47 | static inline void mdp_kms_destroy(struct mdp_kms *mdp_kms) |
48 | { |
49 | msm_kms_destroy(&mdp_kms->base); |
50 | } |
51 | |
52 | /* |
53 | * irq helpers: |
54 | */ |
55 | |
56 | /* For transiently registering for different MDP irqs that various parts |
57 | * of the KMS code need during setup/configuration. These are not |
58 | * necessarily the same as what drm_vblank_get/put() are requesting, and |
59 | * the hysteresis in drm_vblank_put() is not necessarily desirable for |
60 | * internal housekeeping related irq usage. |
61 | */ |
62 | struct mdp_irq { |
63 | struct list_head node; |
64 | uint32_t irqmask; |
65 | bool registered; |
66 | void (*irq)(struct mdp_irq *irq, uint32_t irqstatus); |
67 | }; |
68 | |
69 | void mdp_dispatch_irqs(struct mdp_kms *mdp_kms, uint32_t status); |
70 | void mdp_update_vblank_mask(struct mdp_kms *mdp_kms, uint32_t mask, bool enable); |
71 | void mdp_irq_wait(struct mdp_kms *mdp_kms, uint32_t irqmask); |
72 | void mdp_irq_register(struct mdp_kms *mdp_kms, struct mdp_irq *irq); |
73 | void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq); |
74 | void mdp_irq_update(struct mdp_kms *mdp_kms); |
75 | |
76 | /* |
77 | * pixel format helpers: |
78 | */ |
79 | |
80 | struct mdp_format { |
81 | struct msm_format base; |
82 | enum mdp_bpc bpc_r, bpc_g, bpc_b; |
83 | enum mdp_bpc_alpha bpc_a; |
84 | uint8_t unpack[4]; |
85 | bool alpha_enable, unpack_tight; |
86 | uint8_t cpp, unpack_count; |
87 | enum mdp_fetch_type fetch_type; |
88 | enum mdp_chroma_samp_type chroma_sample; |
89 | bool is_yuv; |
90 | }; |
91 | #define to_mdp_format(x) container_of(x, struct mdp_format, base) |
92 | #define MDP_FORMAT_IS_YUV(mdp_format) ((mdp_format)->is_yuv) |
93 | |
94 | uint32_t mdp_get_formats(uint32_t *formats, uint32_t max_formats, bool rgb_only); |
95 | const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format, uint64_t modifier); |
96 | |
97 | /* MDP capabilities */ |
98 | #define MDP_CAP_SMP BIT(0) /* Shared Memory Pool */ |
99 | #define MDP_CAP_DSC BIT(1) /* VESA Display Stream Compression */ |
100 | #define MDP_CAP_CDM BIT(2) /* Chroma Down Module (HDMI 2.0 YUV) */ |
101 | #define MDP_CAP_SRC_SPLIT BIT(3) /* Source Split of SSPPs */ |
102 | |
103 | /* MDP pipe capabilities */ |
104 | #define MDP_PIPE_CAP_HFLIP BIT(0) |
105 | #define MDP_PIPE_CAP_VFLIP BIT(1) |
106 | #define MDP_PIPE_CAP_SCALE BIT(2) |
107 | #define MDP_PIPE_CAP_CSC BIT(3) |
108 | #define MDP_PIPE_CAP_DECIMATION BIT(4) |
109 | #define MDP_PIPE_CAP_SW_PIX_EXT BIT(5) |
110 | #define MDP_PIPE_CAP_CURSOR BIT(6) |
111 | |
112 | /* MDP layer mixer caps */ |
113 | #define MDP_LM_CAP_DISPLAY BIT(0) |
114 | #define MDP_LM_CAP_WB BIT(1) |
115 | #define MDP_LM_CAP_PAIR BIT(2) |
116 | |
117 | static inline bool pipe_supports_yuv(uint32_t pipe_caps) |
118 | { |
119 | return (pipe_caps & MDP_PIPE_CAP_SCALE) && |
120 | (pipe_caps & MDP_PIPE_CAP_CSC); |
121 | } |
122 | |
123 | enum csc_type { |
124 | CSC_RGB2RGB = 0, |
125 | CSC_YUV2RGB, |
126 | CSC_RGB2YUV, |
127 | CSC_YUV2YUV, |
128 | CSC_MAX |
129 | }; |
130 | |
131 | struct csc_cfg { |
132 | enum csc_type type; |
133 | uint32_t matrix[9]; |
134 | uint32_t pre_bias[3]; |
135 | uint32_t post_bias[3]; |
136 | uint32_t pre_clamp[6]; |
137 | uint32_t post_clamp[6]; |
138 | }; |
139 | |
140 | struct csc_cfg *mdp_get_default_csc_cfg(enum csc_type); |
141 | |
142 | #endif /* __MDP_KMS_H__ */ |
143 | |