1/*
2* Copyright (c) 2011, The Linux Foundation. All rights reserved.
3*
4* Redistribution and use in source and binary forms, with or without
5* modification, are permitted provided that the following conditions are
6* met:
7*    * Redistributions of source code must retain the above copyright
8*      notice, this list of conditions and the following disclaimer.
9*    * Redistributions in binary form must reproduce the above
10*      copyright notice, this list of conditions and the following
11*      disclaimer in the documentation and/or other materials provided
12*      with the distribution.
13*    * Neither the name of The Linux Foundation nor the names of its
14*      contributors may be used to endorse or promote products derived
15*      from this software without specific prior written permission.
16*
17* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#ifndef MDP_WRAPPER_H
31#define MDP_WRAPPER_H
32
33/*
34* In order to make overlay::mdp_wrapper shorter, please do something like:
35* namespace mdpwrap = overlay::mdp_wrapper;
36* */
37
38#include <linux/msm_mdp.h>
39#include <linux/msm_rotator.h>
40#include <sys/ioctl.h>
41#include <utils/Log.h>
42#include <errno.h>
43#include "overlayUtils.h"
44
45#define IOCTL_DEBUG 0
46
47namespace overlay{
48
49namespace mdp_wrapper{
50/* FBIOGET_FSCREENINFO */
51bool getFScreenInfo(int fd, fb_fix_screeninfo& finfo);
52
53/* FBIOGET_VSCREENINFO */
54bool getVScreenInfo(int fd, fb_var_screeninfo& vinfo);
55
56/* FBIOPUT_VSCREENINFO */
57bool setVScreenInfo(int fd, fb_var_screeninfo& vinfo);
58
59/* MSM_ROTATOR_IOCTL_START */
60bool startRotator(int fd, msm_rotator_img_info& rot);
61
62/* MSM_ROTATOR_IOCTL_ROTATE */
63bool rotate(int fd, msm_rotator_data_info& rot);
64
65/* MSMFB_OVERLAY_SET */
66bool setOverlay(int fd, mdp_overlay& ov);
67
68/* MSMFB_OVERLAY_PREPARE */
69bool validateAndSet(const int& fd, mdp_overlay_list& list);
70
71/* MSM_ROTATOR_IOCTL_FINISH */
72bool endRotator(int fd, int sessionId);
73
74/* MSMFB_OVERLAY_UNSET */
75bool unsetOverlay(int fd, int ovId);
76
77/* MSMFB_OVERLAY_GET */
78bool getOverlay(int fd, mdp_overlay& ov);
79
80/* MSMFB_OVERLAY_PLAY */
81bool play(int fd, msmfb_overlay_data& od);
82
83/* MSMFB_OVERLAY_3D */
84bool set3D(int fd, msmfb_overlay_3d& ov);
85
86/* MSMFB_DISPLAY_COMMIT */
87bool displayCommit(int fd);
88
89/* MSMFB_WRITEBACK_INIT, MSMFB_WRITEBACK_START */
90bool wbInitStart(int fbfd);
91
92/* MSMFB_WRITEBACK_STOP, MSMFB_WRITEBACK_TERMINATE */
93bool wbStopTerminate(int fbfd);
94
95/* MSMFB_WRITEBACK_QUEUE_BUFFER */
96bool wbQueueBuffer(int fbfd, struct msmfb_data& fbData);
97
98/* MSMFB_WRITEBACK_DEQUEUE_BUFFER */
99bool wbDequeueBuffer(int fbfd, struct msmfb_data& fbData);
100
101/* MSMFB_SECURE */
102bool setSecureBuffer(int fbFd, struct msmfb_secure_config& config);
103
104/* the following are helper functions for dumping
105 * msm_mdp and friends*/
106void dump(const char* const s, const msmfb_overlay_data& ov);
107void dump(const char* const s, const msmfb_data& ov);
108void dump(const char* const s, const mdp_overlay& ov);
109void dump(const char* const s, const msmfb_overlay_3d& ov);
110void dump(const char* const s, const uint32_t u[], uint32_t cnt);
111void dump(const char* const s, const msmfb_img& ov);
112void dump(const char* const s, const mdp_rect& ov);
113
114/* and rotator */
115void dump(const char* const s, const msm_rotator_img_info& rot);
116void dump(const char* const s, const msm_rotator_data_info& rot);
117
118/* info */
119void dump(const char* const s, const fb_fix_screeninfo& finfo);
120void dump(const char* const s, const fb_var_screeninfo& vinfo);
121
122//---------------Inlines -------------------------------------
123
124inline bool getFScreenInfo(int fd, fb_fix_screeninfo& finfo) {
125    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) < 0) {
126        ALOGE("Failed to call ioctl FBIOGET_FSCREENINFO err=%s",
127                strerror(errno));
128        return false;
129    }
130    return true;
131}
132
133inline bool getVScreenInfo(int fd, fb_var_screeninfo& vinfo) {
134    if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0) {
135        ALOGE("Failed to call ioctl FBIOGET_VSCREENINFO err=%s",
136                strerror(errno));
137        return false;
138    }
139    return true;
140}
141
142inline bool setVScreenInfo(int fd, fb_var_screeninfo& vinfo) {
143    if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo) < 0) {
144        ALOGE("Failed to call ioctl FBIOPUT_VSCREENINFO err=%s",
145                strerror(errno));
146        return false;
147    }
148    return true;
149}
150
151inline bool startRotator(int fd, msm_rotator_img_info& rot) {
152    if (ioctl(fd, MSM_ROTATOR_IOCTL_START, &rot) < 0){
153        ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_START err=%s",
154                strerror(errno));
155        return false;
156    }
157    return true;
158}
159
160inline bool rotate(int fd, msm_rotator_data_info& rot) {
161    if (ioctl(fd, MSM_ROTATOR_IOCTL_ROTATE, &rot) < 0) {
162        ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_ROTATE err=%s",
163                strerror(errno));
164        return false;
165    }
166    return true;
167}
168
169inline bool setOverlay(int fd, mdp_overlay& ov) {
170    if (ioctl(fd, MSMFB_OVERLAY_SET, &ov) < 0) {
171        ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s",
172                strerror(errno));
173        return false;
174    }
175    return true;
176}
177
178inline bool validateAndSet(const int& fd, mdp_overlay_list& list) {
179    if (ioctl(fd, MSMFB_OVERLAY_PREPARE, &list) < 0) {
180        ALOGD_IF(IOCTL_DEBUG, "Failed to call ioctl MSMFB_OVERLAY_PREPARE "
181                "err=%s", strerror(errno));
182        return false;
183    }
184    return true;
185}
186
187inline bool endRotator(int fd, uint32_t sessionId) {
188    if (ioctl(fd, MSM_ROTATOR_IOCTL_FINISH, &sessionId) < 0) {
189        ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_FINISH err=%s",
190                strerror(errno));
191        return false;
192    }
193    return true;
194}
195
196inline bool unsetOverlay(int fd, int ovId) {
197    if (ioctl(fd, MSMFB_OVERLAY_UNSET, &ovId) < 0) {
198        ALOGE("Failed to call ioctl MSMFB_OVERLAY_UNSET err=%s",
199                strerror(errno));
200        return false;
201    }
202    return true;
203}
204
205inline bool getOverlay(int fd, mdp_overlay& ov) {
206    if (ioctl(fd, MSMFB_OVERLAY_GET, &ov) < 0) {
207        ALOGE("Failed to call ioctl MSMFB_OVERLAY_GET err=%s",
208                strerror(errno));
209        return false;
210    }
211    return true;
212}
213
214inline bool play(int fd, msmfb_overlay_data& od) {
215    if (ioctl(fd, MSMFB_OVERLAY_PLAY, &od) < 0) {
216        ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s",
217                strerror(errno));
218        return false;
219    }
220    return true;
221}
222
223inline bool set3D(int fd, msmfb_overlay_3d& ov) {
224    if (ioctl(fd, MSMFB_OVERLAY_3D, &ov) < 0) {
225        ALOGE("Failed to call ioctl MSMFB_OVERLAY_3D err=%s",
226                strerror(errno));
227        return false;
228    }
229    return true;
230}
231
232inline bool displayCommit(int fd, mdp_display_commit& info) {
233    if(ioctl(fd, MSMFB_DISPLAY_COMMIT, &info) == -1) {
234        ALOGE("Failed to call ioctl MSMFB_DISPLAY_COMMIT err=%s",
235                strerror(errno));
236        return false;
237    }
238    return true;
239}
240
241inline bool wbInitStart(int fbfd) {
242    if(ioctl(fbfd, MSMFB_WRITEBACK_INIT, NULL) < 0) {
243        ALOGE("Failed to call ioctl MSMFB_WRITEBACK_INIT err=%s",
244                strerror(errno));
245        return false;
246    }
247    if(ioctl(fbfd, MSMFB_WRITEBACK_START, NULL) < 0) {
248        ALOGE("Failed to call ioctl MSMFB_WRITEBACK_START err=%s",
249                strerror(errno));
250        return false;
251    }
252    return true;
253}
254
255inline bool wbStopTerminate(int fbfd) {
256    if(ioctl(fbfd, MSMFB_WRITEBACK_STOP, NULL) < 0) {
257        ALOGE("Failed to call ioctl MSMFB_WRITEBACK_STOP err=%s",
258                strerror(errno));
259        return false;
260    }
261    if(ioctl(fbfd, MSMFB_WRITEBACK_TERMINATE, NULL) < 0) {
262        ALOGE("Failed to call ioctl MSMFB_WRITEBACK_TERMINATE err=%s",
263                strerror(errno));
264        return false;
265    }
266    return true;
267}
268
269inline bool wbQueueBuffer(int fbfd, struct msmfb_data& fbData) {
270    if(ioctl(fbfd, MSMFB_WRITEBACK_QUEUE_BUFFER, &fbData) < 0) {
271        ALOGE("Failed to call ioctl MSMFB_WRITEBACK_QUEUE_BUFFER err=%s",
272                strerror(errno));
273        return false;
274    }
275    return true;
276}
277
278inline bool wbDequeueBuffer(int fbfd, struct msmfb_data& fbData) {
279    if(ioctl(fbfd, MSMFB_WRITEBACK_DEQUEUE_BUFFER, &fbData) < 0) {
280        ALOGE("Failed to call ioctl MSMFB_WRITEBACK_DEQUEUE_BUFFER err=%s",
281                strerror(errno));
282        return false;
283    }
284    return true;
285}
286
287inline bool setSecureBuffer(int fbFd, struct msmfb_secure_config& config) {
288    if(ioctl(fbFd, MSMFB_SECURE, &config) < 0) {
289        ALOGE("Failed to call ioctl MSMFB_SECURE err=%s buf_fd=%d enable=%d",
290                strerror(errno), config.fd, config.enable);
291        return false;
292    }
293    return true;
294}
295
296/* dump funcs */
297inline void dump(const char* const s, const msmfb_overlay_data& ov) {
298    ALOGE("%s msmfb_overlay_data id=%d",
299            s, ov.id);
300    dump("data", ov.data);
301}
302inline void dump(const char* const s, const msmfb_data& ov) {
303    ALOGE("%s msmfb_data offset=%d memid=%d id=%d flags=0x%x priv=%d",
304            s, ov.offset, ov.memory_id, ov.id, ov.flags, ov.priv);
305}
306inline void dump(const char* const s, const mdp_overlay& ov) {
307    ALOGE("%s mdp_overlay z=%d fg=%d alpha=%d mask=%d flags=0x%x id=%d",
308            s, ov.z_order, ov.is_fg, ov.alpha,
309            ov.transp_mask, ov.flags, ov.id);
310    dump("src", ov.src);
311    dump("src_rect", ov.src_rect);
312    dump("dst_rect", ov.dst_rect);
313    /*
314    Commented off to prevent verbose logging, since user_data could have 8 or so
315    fields which are mostly 0
316    dump("user_data", ov.user_data,
317            sizeof(ov.user_data)/sizeof(ov.user_data[0]));
318    */
319}
320inline void dump(const char* const s, const msmfb_img& ov) {
321    ALOGE("%s msmfb_img w=%d h=%d format=%d %s",
322            s, ov.width, ov.height, ov.format,
323            overlay::utils::getFormatString(ov.format));
324}
325inline void dump(const char* const s, const mdp_rect& ov) {
326    ALOGE("%s mdp_rect x=%d y=%d w=%d h=%d",
327            s, ov.x, ov.y, ov.w, ov.h);
328}
329
330inline void dump(const char* const s, const msmfb_overlay_3d& ov) {
331    ALOGE("%s msmfb_overlay_3d 3d=%d w=%d h=%d",
332            s, ov.is_3d, ov.width, ov.height);
333
334}
335inline void dump(const char* const s, const uint32_t u[], uint32_t cnt) {
336    ALOGE("%s user_data cnt=%d", s, cnt);
337    for(uint32_t i=0; i < cnt; ++i) {
338        ALOGE("i=%d val=%d", i, u[i]);
339    }
340}
341inline void dump(const char* const s, const msm_rotator_img_info& rot) {
342    ALOGE("%s msm_rotator_img_info sessid=%u dstx=%d dsty=%d rot=%d, ena=%d scale=%d",
343            s, rot.session_id, rot.dst_x, rot.dst_y,
344            rot.rotations, rot.enable, rot.downscale_ratio);
345    dump("src", rot.src);
346    dump("dst", rot.dst);
347    dump("src_rect", rot.src_rect);
348}
349inline void dump(const char* const s, const msm_rotator_data_info& rot) {
350    ALOGE("%s msm_rotator_data_info sessid=%u verkey=%d",
351            s, rot.session_id, rot.version_key);
352    dump("src", rot.src);
353    dump("dst", rot.dst);
354    dump("src_chroma", rot.src_chroma);
355    dump("dst_chroma", rot.dst_chroma);
356}
357inline void dump(const char* const s, const fb_fix_screeninfo& finfo) {
358    ALOGE("%s fb_fix_screeninfo type=%d", s, finfo.type);
359}
360inline void dump(const char* const s, const fb_var_screeninfo& vinfo) {
361    ALOGE("%s fb_var_screeninfo xres=%d yres=%d",
362            s, vinfo.xres, vinfo.yres);
363}
364
365} // mdp_wrapper
366
367} // overlay
368
369#endif // MDP_WRAPPER_H
370