1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#ifndef __MDP4_KMS_H__
19#define __MDP4_KMS_H__
20
21#include <drm/drm_panel.h>
22
23#include "msm_drv.h"
24#include "msm_kms.h"
25#include "disp/mdp_kms.h"
26#include "mdp4.xml.h"
27
28struct device_node;
29
30struct mdp4_kms {
31 struct mdp_kms base;
32
33 struct drm_device *dev;
34
35 int rev;
36
37 void __iomem *mmio;
38
39 struct regulator *vdd;
40
41 struct clk *clk;
42 struct clk *pclk;
43 struct clk *lut_clk;
44 struct clk *axi_clk;
45
46 struct mdp_irq error_handler;
47
48 bool rpm_enabled;
49
50
51 struct drm_gem_object *blank_cursor_bo;
52 uint64_t blank_cursor_iova;
53};
54#define to_mdp4_kms(x) container_of(x, struct mdp4_kms, base)
55
56
57struct mdp4_platform_config {
58 struct iommu_domain *iommu;
59 uint32_t max_clk;
60};
61
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
72static inline uint32_t pipe2flush(enum mdp4_pipe pipe)
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;
78 case RGB2: return MDP4_OVERLAY_FLUSH_RGB2;
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
112static inline uint32_t mixercfg(uint32_t mixer_cfg, int mixer,
113 enum mdp4_pipe pipe, enum mdp_mixer_stage_id stage)
114{
115 switch (pipe) {
116 case VG1:
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) |
120 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1);
121 break;
122 case VG2:
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) |
126 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1);
127 break;
128 case RGB1:
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) |
132 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1);
133 break;
134 case RGB2:
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) |
138 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1);
139 break;
140 case RGB3:
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) |
144 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1);
145 break;
146 case VG3:
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) |
150 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1);
151 break;
152 case VG4:
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) |
156 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1);
157 break;
158 default:
159 WARN(1, "invalid pipe");
160 break;
161 }
162
163 return mixer_cfg;
164}
165
166int mdp4_disable(struct mdp4_kms *mdp4_kms);
167int mdp4_enable(struct mdp4_kms *mdp4_kms);
168
169void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
170 uint32_t old_irqmask);
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);
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
178static inline uint32_t mdp4_pipe_caps(enum mdp4_pipe pipe)
179{
180 switch (pipe) {
181 case VG1:
182 case VG2:
183 case VG3:
184 case VG4:
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;
191 default:
192 return 0;
193 }
194}
195
196enum mdp4_pipe mdp4_plane_pipe(struct drm_plane *plane);
197struct drm_plane *mdp4_plane_init(struct drm_device *dev,
198 enum mdp4_pipe pipe_id, bool private_plane);
199
200uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc);
201void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config);
202void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf, int mixer);
203void mdp4_crtc_wait_for_commit_done(struct drm_crtc *crtc);
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
211long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate);
212struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev,
213 struct device_node *panel_node);
214
215struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev,
216 struct device_node *panel_node, struct drm_encoder *encoder);
217
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
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
236#ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING
237
238
239
240
241static inline void *mdp4_find_pdata(const char *devname)
242{
243 struct device *dev;
244 dev = bus_find_device_by_name(&platform_bus_type, NULL, devname);
245 return dev ? dev->platform_data : NULL;
246}
247#endif
248
249#endif
250