]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
drm/msm/dsi: Fix potential NULL pointer dereference in msm_dsi_modeset_init
[mirror_ubuntu-focal-kernel.git] / drivers / gpu / drm / msm / mdp / mdp4 / mdp4_kms.h
CommitLineData
c8afe684
RC
1/*
2 * Copyright (C) 2013 Red Hat
3 * Author: Rob Clark <robdclark@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef __MDP4_KMS_H__
19#define __MDP4_KMS_H__
20
78f27b1c
MY
21#include <drm/drm_panel.h>
22
c8afe684 23#include "msm_drv.h"
dd2da6e3 24#include "msm_kms.h"
10a02eb6 25#include "mdp/mdp_kms.h"
c8afe684
RC
26#include "mdp4.xml.h"
27
78f27b1c 28struct device_node;
3e87599b 29
c8afe684 30struct mdp4_kms {
9e0efa63 31 struct mdp_kms base;
c8afe684
RC
32
33 struct drm_device *dev;
34
35 int rev;
36
c8afe684
RC
37 void __iomem *mmio;
38
c8afe684
RC
39 struct regulator *vdd;
40
41 struct clk *clk;
42 struct clk *pclk;
43 struct clk *lut_clk;
e8abb5b5 44 struct clk *axi_clk;
c8afe684 45
9e0efa63 46 struct mdp_irq error_handler;
7d8d9f67 47
cd792726
AT
48 bool rpm_enabled;
49
7d8d9f67
RC
50 /* empty/blank cursor bo to use when cursor is "disabled" */
51 struct drm_gem_object *blank_cursor_bo;
78babc16 52 uint64_t blank_cursor_iova;
c8afe684
RC
53};
54#define to_mdp4_kms(x) container_of(x, struct mdp4_kms, base)
55
56/* platform config data (ie. from DT, or pdata) */
57struct mdp4_platform_config {
58 struct iommu_domain *iommu;
59 uint32_t max_clk;
60};
61
c8afe684
RC
62static inline void mdp4_write(struct mdp4_kms *mdp4_kms, u32 reg, u32 data)
63{
64 msm_writel(data, mdp4_kms->mmio + reg);
65}
66
67static inline u32 mdp4_read(struct mdp4_kms *mdp4_kms, u32 reg)
68{
69 return msm_readl(mdp4_kms->mmio + reg);
70}
71
22ba8b6b 72static inline uint32_t pipe2flush(enum mdp4_pipe pipe)
c8afe684
RC
73{
74 switch (pipe) {
75 case VG1: return MDP4_OVERLAY_FLUSH_VG1;
76 case VG2: return MDP4_OVERLAY_FLUSH_VG2;
77 case RGB1: return MDP4_OVERLAY_FLUSH_RGB1;
f9a1ca5c 78 case RGB2: return MDP4_OVERLAY_FLUSH_RGB2;
c8afe684
RC
79 default: return 0;
80 }
81}
82
83static inline uint32_t ovlp2flush(int ovlp)
84{
85 switch (ovlp) {
86 case 0: return MDP4_OVERLAY_FLUSH_OVLP0;
87 case 1: return MDP4_OVERLAY_FLUSH_OVLP1;
88 default: return 0;
89 }
90}
91
92static inline uint32_t dma2irq(enum mdp4_dma dma)
93{
94 switch (dma) {
95 case DMA_P: return MDP4_IRQ_DMA_P_DONE;
96 case DMA_S: return MDP4_IRQ_DMA_S_DONE;
97 case DMA_E: return MDP4_IRQ_DMA_E_DONE;
98 default: return 0;
99 }
100}
101
102static inline uint32_t dma2err(enum mdp4_dma dma)
103{
104 switch (dma) {
105 case DMA_P: return MDP4_IRQ_PRIMARY_INTF_UDERRUN;
106 case DMA_S: return 0; // ???
107 case DMA_E: return MDP4_IRQ_EXTERNAL_INTF_UDERRUN;
108 default: return 0;
109 }
110}
111
d65bd0e4
RC
112static inline uint32_t mixercfg(uint32_t mixer_cfg, int mixer,
113 enum mdp4_pipe pipe, enum mdp_mixer_stage_id stage)
a8623918 114{
a8623918
RC
115 switch (pipe) {
116 case VG1:
d65bd0e4
RC
117 mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE0__MASK |
118 MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1);
119 mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE0(stage) |
a8623918
RC
120 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1);
121 break;
122 case VG2:
d65bd0e4
RC
123 mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE1__MASK |
124 MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1);
125 mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE1(stage) |
a8623918
RC
126 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1);
127 break;
128 case RGB1:
d65bd0e4
RC
129 mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE2__MASK |
130 MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1);
131 mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE2(stage) |
a8623918
RC
132 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1);
133 break;
134 case RGB2:
d65bd0e4
RC
135 mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE3__MASK |
136 MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1);
137 mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE3(stage) |
a8623918
RC
138 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1);
139 break;
140 case RGB3:
d65bd0e4
RC
141 mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE4__MASK |
142 MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1);
143 mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE4(stage) |
a8623918
RC
144 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1);
145 break;
146 case VG3:
d65bd0e4
RC
147 mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE5__MASK |
148 MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1);
149 mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE5(stage) |
a8623918
RC
150 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1);
151 break;
152 case VG4:
d65bd0e4
RC
153 mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE6__MASK |
154 MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1);
155 mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE6(stage) |
a8623918
RC
156 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1);
157 break;
158 default:
2abd1c88 159 WARN(1, "invalid pipe");
a8623918
RC
160 break;
161 }
162
163 return mixer_cfg;
164}
165
c8afe684
RC
166int mdp4_disable(struct mdp4_kms *mdp4_kms);
167int mdp4_enable(struct mdp4_kms *mdp4_kms);
168
29f034d7 169void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
170 uint32_t old_irqmask);
c8afe684
RC
171void mdp4_irq_preinstall(struct msm_kms *kms);
172int mdp4_irq_postinstall(struct msm_kms *kms);
173void mdp4_irq_uninstall(struct msm_kms *kms);
174irqreturn_t mdp4_irq(struct msm_kms *kms);
c8afe684
RC
175int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
176void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
177
3498409f 178static inline uint32_t mdp4_pipe_caps(enum mdp4_pipe pipe)
7ca12718
SV
179{
180 switch (pipe) {
181 case VG1:
182 case VG2:
183 case VG3:
184 case VG4:
3498409f 185 return MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
186 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC;
187 case RGB1:
188 case RGB2:
189 case RGB3:
190 return MDP_PIPE_CAP_SCALE;
7ca12718 191 default:
3498409f 192 return 0;
7ca12718
SV
193 }
194}
195
22ba8b6b 196enum mdp4_pipe mdp4_plane_pipe(struct drm_plane *plane);
c8afe684 197struct drm_plane *mdp4_plane_init(struct drm_device *dev,
22ba8b6b 198 enum mdp4_pipe pipe_id, bool private_plane);
c8afe684
RC
199
200uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc);
c8afe684 201void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config);
d65bd0e4 202void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf, int mixer);
0a5c9aad 203void mdp4_crtc_wait_for_commit_done(struct drm_crtc *crtc);
c8afe684
RC
204struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
205 struct drm_plane *plane, int id, int ovlp_id,
206 enum mdp4_dma dma_id);
207
208long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate);
209struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev);
210
3e87599b
RC
211long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate);
212struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev,
a6bf7f63 213 struct device_node *panel_node);
3e87599b
RC
214
215struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev,
a6bf7f63 216 struct device_node *panel_node, struct drm_encoder *encoder);
3e87599b 217
776638e7
VSB
218#ifdef CONFIG_DRM_MSM_DSI
219struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev);
220#else
221static inline struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev)
222{
223 return ERR_PTR(-ENODEV);
224}
225#endif
226
3e87599b
RC
227#ifdef CONFIG_COMMON_CLK
228struct clk *mpd4_lvds_pll_init(struct drm_device *dev);
229#else
230static inline struct clk *mpd4_lvds_pll_init(struct drm_device *dev)
231{
232 return ERR_PTR(-ENODEV);
233}
234#endif
235
6490ad47 236#ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING
c8afe684
RC
237/* bus scaling data is associated with extra pointless platform devices,
238 * "dtv", etc.. this is a bit of a hack, but we need a way for encoders
239 * to find their pdata to make the bus-scaling stuff work.
240 */
241static inline void *mdp4_find_pdata(const char *devname)
242{
243 struct device *dev;
8dcbde0f 244 dev = bus_find_device_by_name(&platform_bus_type, NULL, devname);
c8afe684
RC
245 return dev ? dev->platform_data : NULL;
246}
247#endif
248
249#endif /* __MDP4_KMS_H__ */