• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 __MDP5_KMS_H__
19 #define __MDP5_KMS_H__
20 
21 #include "msm_drv.h"
22 #include "msm_kms.h"
23 #include "mdp/mdp_kms.h"
24 /* dynamic offsets used by mdp5.xml.h (initialized in mdp5_kms.c) */
25 #define MDP5_MAX_BASES		8
26 struct mdp5_sub_block {
27 	int	count;
28 	uint32_t base[MDP5_MAX_BASES];
29 };
30 struct mdp5_config {
31 	char  *name;
32 	struct mdp5_sub_block ctl;
33 	struct mdp5_sub_block pipe_vig;
34 	struct mdp5_sub_block pipe_rgb;
35 	struct mdp5_sub_block pipe_dma;
36 	struct mdp5_sub_block lm;
37 	struct mdp5_sub_block dspp;
38 	struct mdp5_sub_block ad;
39 	struct mdp5_sub_block intf;
40 };
41 extern const struct mdp5_config *mdp5_cfg;
42 #include "mdp5.xml.h"
43 #include "mdp5_smp.h"
44 
45 struct mdp5_kms {
46 	struct mdp_kms base;
47 
48 	struct drm_device *dev;
49 
50 	int rev;
51 	const struct mdp5_config *hw_cfg;
52 
53 	/* mapper-id used to request GEM buffer mapped for scanout: */
54 	int id;
55 	struct msm_mmu *mmu;
56 
57 	/* for tracking smp allocation amongst pipes: */
58 	mdp5_smp_state_t smp_state;
59 	struct mdp5_client_smp_state smp_client_state[CID_MAX];
60 	int smp_blk_cnt;
61 
62 	/* io/register spaces: */
63 	void __iomem *mmio, *vbif;
64 
65 	struct regulator *vdd;
66 
67 	struct clk *axi_clk;
68 	struct clk *ahb_clk;
69 	struct clk *src_clk;
70 	struct clk *core_clk;
71 	struct clk *lut_clk;
72 	struct clk *vsync_clk;
73 
74 	struct hdmi *hdmi;
75 
76 	struct mdp_irq error_handler;
77 };
78 #define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base)
79 
80 /* platform config data (ie. from DT, or pdata) */
81 struct mdp5_platform_config {
82 	struct iommu_domain *iommu;
83 	uint32_t max_clk;
84 	int smp_blk_cnt;
85 };
86 
mdp5_write(struct mdp5_kms * mdp5_kms,u32 reg,u32 data)87 static inline void mdp5_write(struct mdp5_kms *mdp5_kms, u32 reg, u32 data)
88 {
89 	msm_writel(data, mdp5_kms->mmio + reg);
90 }
91 
mdp5_read(struct mdp5_kms * mdp5_kms,u32 reg)92 static inline u32 mdp5_read(struct mdp5_kms *mdp5_kms, u32 reg)
93 {
94 	return msm_readl(mdp5_kms->mmio + reg);
95 }
96 
pipe2name(enum mdp5_pipe pipe)97 static inline const char *pipe2name(enum mdp5_pipe pipe)
98 {
99 	static const char *names[] = {
100 #define NAME(n) [SSPP_ ## n] = #n
101 		NAME(VIG0), NAME(VIG1), NAME(VIG2),
102 		NAME(RGB0), NAME(RGB1), NAME(RGB2),
103 		NAME(DMA0), NAME(DMA1),
104 		NAME(VIG3), NAME(RGB3),
105 #undef NAME
106 	};
107 	return names[pipe];
108 }
109 
pipe2flush(enum mdp5_pipe pipe)110 static inline uint32_t pipe2flush(enum mdp5_pipe pipe)
111 {
112 	switch (pipe) {
113 	case SSPP_VIG0: return MDP5_CTL_FLUSH_VIG0;
114 	case SSPP_VIG1: return MDP5_CTL_FLUSH_VIG1;
115 	case SSPP_VIG2: return MDP5_CTL_FLUSH_VIG2;
116 	case SSPP_RGB0: return MDP5_CTL_FLUSH_RGB0;
117 	case SSPP_RGB1: return MDP5_CTL_FLUSH_RGB1;
118 	case SSPP_RGB2: return MDP5_CTL_FLUSH_RGB2;
119 	case SSPP_DMA0: return MDP5_CTL_FLUSH_DMA0;
120 	case SSPP_DMA1: return MDP5_CTL_FLUSH_DMA1;
121 	case SSPP_VIG3: return MDP5_CTL_FLUSH_VIG3;
122 	case SSPP_RGB3: return MDP5_CTL_FLUSH_RGB3;
123 	default:        return 0;
124 	}
125 }
126 
pipe2nclients(enum mdp5_pipe pipe)127 static inline int pipe2nclients(enum mdp5_pipe pipe)
128 {
129 	switch (pipe) {
130 	case SSPP_RGB0:
131 	case SSPP_RGB1:
132 	case SSPP_RGB2:
133 	case SSPP_RGB3:
134 		return 1;
135 	default:
136 		return 3;
137 	}
138 }
139 
pipe2client(enum mdp5_pipe pipe,int plane)140 static inline enum mdp5_client_id pipe2client(enum mdp5_pipe pipe, int plane)
141 {
142 	WARN_ON(plane >= pipe2nclients(pipe));
143 	switch (pipe) {
144 	case SSPP_VIG0: return CID_VIG0_Y + plane;
145 	case SSPP_VIG1: return CID_VIG1_Y + plane;
146 	case SSPP_VIG2: return CID_VIG2_Y + plane;
147 	case SSPP_RGB0: return CID_RGB0;
148 	case SSPP_RGB1: return CID_RGB1;
149 	case SSPP_RGB2: return CID_RGB2;
150 	case SSPP_DMA0: return CID_DMA0_Y + plane;
151 	case SSPP_DMA1: return CID_DMA1_Y + plane;
152 	case SSPP_VIG3: return CID_VIG3_Y + plane;
153 	case SSPP_RGB3: return CID_RGB3;
154 	default:        return CID_UNUSED;
155 	}
156 }
157 
mixer2flush(int lm)158 static inline uint32_t mixer2flush(int lm)
159 {
160 	switch (lm) {
161 	case 0:  return MDP5_CTL_FLUSH_LM0;
162 	case 1:  return MDP5_CTL_FLUSH_LM1;
163 	case 2:  return MDP5_CTL_FLUSH_LM2;
164 	default: return 0;
165 	}
166 }
167 
intf2err(int intf)168 static inline uint32_t intf2err(int intf)
169 {
170 	switch (intf) {
171 	case 0:  return MDP5_IRQ_INTF0_UNDER_RUN;
172 	case 1:  return MDP5_IRQ_INTF1_UNDER_RUN;
173 	case 2:  return MDP5_IRQ_INTF2_UNDER_RUN;
174 	case 3:  return MDP5_IRQ_INTF3_UNDER_RUN;
175 	default: return 0;
176 	}
177 }
178 
intf2vblank(int intf)179 static inline uint32_t intf2vblank(int intf)
180 {
181 	switch (intf) {
182 	case 0:  return MDP5_IRQ_INTF0_VSYNC;
183 	case 1:  return MDP5_IRQ_INTF1_VSYNC;
184 	case 2:  return MDP5_IRQ_INTF2_VSYNC;
185 	case 3:  return MDP5_IRQ_INTF3_VSYNC;
186 	default: return 0;
187 	}
188 }
189 
190 int mdp5_disable(struct mdp5_kms *mdp5_kms);
191 int mdp5_enable(struct mdp5_kms *mdp5_kms);
192 
193 void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask);
194 void mdp5_irq_preinstall(struct msm_kms *kms);
195 int mdp5_irq_postinstall(struct msm_kms *kms);
196 void mdp5_irq_uninstall(struct msm_kms *kms);
197 irqreturn_t mdp5_irq(struct msm_kms *kms);
198 int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
199 void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
200 
201 static inline
mdp5_get_formats(enum mdp5_pipe pipe,uint32_t * pixel_formats,uint32_t max_formats)202 uint32_t mdp5_get_formats(enum mdp5_pipe pipe, uint32_t *pixel_formats,
203 		uint32_t max_formats)
204 {
205 	/* TODO when we have YUV, we need to filter supported formats
206 	 * based on pipe id..
207 	 */
208 	return mdp_get_formats(pixel_formats, max_formats);
209 }
210 
211 void mdp5_plane_install_properties(struct drm_plane *plane,
212 		struct drm_mode_object *obj);
213 void mdp5_plane_set_scanout(struct drm_plane *plane,
214 		struct drm_framebuffer *fb);
215 int mdp5_plane_mode_set(struct drm_plane *plane,
216 		struct drm_crtc *crtc, struct drm_framebuffer *fb,
217 		int crtc_x, int crtc_y,
218 		unsigned int crtc_w, unsigned int crtc_h,
219 		uint32_t src_x, uint32_t src_y,
220 		uint32_t src_w, uint32_t src_h);
221 void mdp5_plane_complete_flip(struct drm_plane *plane);
222 enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane);
223 struct drm_plane *mdp5_plane_init(struct drm_device *dev,
224 		enum mdp5_pipe pipe, bool private_plane);
225 
226 uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc);
227 
228 void mdp5_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file);
229 void mdp5_crtc_set_intf(struct drm_crtc *crtc, int intf,
230 		enum mdp5_intf intf_id);
231 void mdp5_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane);
232 void mdp5_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane);
233 struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
234 		struct drm_plane *plane, int id);
235 
236 struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, int intf,
237 		enum mdp5_intf intf_id);
238 
239 #endif /* __MDP5_KMS_H__ */
240