blob: c42e9c18a0246fab97fec3c4b796170d1d7c28d4 [file] [log] [blame]
Dees Troy62b75ab2014-05-02 13:20:33 +00001/*
2 * Copyright (c) 2013, 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#include <stdbool.h>
31#include <stdlib.h>
32#include <unistd.h>
33
34#include <errno.h>
35#include <fcntl.h>
36#include <stdio.h>
37
38#include <sys/ioctl.h>
39#include <sys/mman.h>
40#include <sys/types.h>
41
42#include <linux/fb.h>
43#include <linux/kd.h>
44
45#ifdef MSM_BSP
46#include <linux/msm_mdp.h>
47#include <linux/msm_ion.h>
48#endif
49
50#include <pixelflinger/pixelflinger.h>
51
52#include "minui.h"
53
54#define MDP_V4_0 400
55
56#ifdef MSM_BSP
57#define ALIGN(x, align) (((x) + ((align)-1)) & ~((align)-1))
58
59typedef struct {
60 unsigned char *mem_buf;
61 int size;
62 int ion_fd;
63 int mem_fd;
64 struct ion_handle_data handle_data;
65} memInfo;
66
67static int overlay_id = MSMFB_NEW_REQUEST;
68static memInfo mem_info;
69
70static int map_mdp_pixel_format()
71{
72 int format = MDP_RGB_565;
73#if defined(RECOVERY_BGRA)
74 format = MDP_BGRA_8888;
Kra1o577568592015-10-14 18:09:54 +020075#elif defined(RECOVERY_RGBA)
76 format = MDP_RGBA_8888;
Dees Troy62b75ab2014-05-02 13:20:33 +000077#elif defined(RECOVERY_RGBX)
78 format = MDP_RGBA_8888;
79#endif
80 return format;
81}
Dees Troy62b75ab2014-05-02 13:20:33 +000082
83static bool overlay_supported = false;
84
85bool target_has_overlay(char *version)
86{
87 int ret;
88 int mdp_version;
89
90 if (strlen(version) >= 8) {
91 if(!strncmp(version, "msmfb", strlen("msmfb"))) {
92 char str_ver[4];
93 memcpy(str_ver, version + strlen("msmfb"), 3);
94 str_ver[3] = '\0';
95 mdp_version = atoi(str_ver);
96 if (mdp_version >= MDP_V4_0) {
97 overlay_supported = true;
98 }
99 } else if (!strncmp(version, "mdssfb", strlen("mdssfb"))) {
100 overlay_supported = true;
101 }
102 }
103
104 return overlay_supported;
105}
106
Dees Troy62b75ab2014-05-02 13:20:33 +0000107int free_ion_mem(void) {
108 if (!overlay_supported)
109 return -EINVAL;
110
111 int ret = 0;
112
113 if (mem_info.mem_buf)
114 munmap(mem_info.mem_buf, mem_info.size);
115
116 if (mem_info.ion_fd >= 0) {
117 ret = ioctl(mem_info.ion_fd, ION_IOC_FREE, &mem_info.handle_data);
118 if (ret < 0)
119 perror("free_mem failed ");
120 }
121
122 if (mem_info.mem_fd >= 0)
123 close(mem_info.mem_fd);
124 if (mem_info.ion_fd >= 0)
125 close(mem_info.ion_fd);
126
127 memset(&mem_info, 0, sizeof(mem_info));
128 mem_info.mem_fd = -1;
129 mem_info.ion_fd = -1;
130 return 0;
131}
132
133int alloc_ion_mem(unsigned int size)
134{
135 if (!overlay_supported)
136 return -EINVAL;
137 int result;
138 struct ion_fd_data fd_data;
139 struct ion_allocation_data ionAllocData;
140
141 mem_info.ion_fd = open("/dev/ion", O_RDWR|O_DSYNC);
142 if (mem_info.ion_fd < 0) {
143 perror("ERROR: Can't open ion ");
144 return -errno;
145 }
146
147 ionAllocData.flags = 0;
148 ionAllocData.len = size;
149 ionAllocData.align = sysconf(_SC_PAGESIZE);
Kra1o5de50c5f2015-04-23 21:46:36 +0200150#ifdef NEW_ION_HEAP
151 ionAllocData.heap_id_mask =
152#else
Dees Troy62b75ab2014-05-02 13:20:33 +0000153 ionAllocData.heap_mask =
Kra1o5de50c5f2015-04-23 21:46:36 +0200154#endif
Dees Troy62b75ab2014-05-02 13:20:33 +0000155 ION_HEAP(ION_IOMMU_HEAP_ID) |
156 ION_HEAP(ION_SYSTEM_CONTIG_HEAP_ID);
157
158 result = ioctl(mem_info.ion_fd, ION_IOC_ALLOC, &ionAllocData);
159 if(result){
160 perror("ION_IOC_ALLOC Failed ");
161 close(mem_info.ion_fd);
162 return result;
163 }
164
165 fd_data.handle = ionAllocData.handle;
166 mem_info.handle_data.handle = ionAllocData.handle;
167 result = ioctl(mem_info.ion_fd, ION_IOC_MAP, &fd_data);
168 if (result) {
169 perror("ION_IOC_MAP Failed ");
170 free_ion_mem();
171 return result;
172 }
173 mem_info.mem_buf = (unsigned char *)mmap(NULL, size, PROT_READ |
174 PROT_WRITE, MAP_SHARED, fd_data.fd, 0);
175 mem_info.mem_fd = fd_data.fd;
176
177 if (!mem_info.mem_buf) {
178 perror("ERROR: mem_buf MAP_FAILED ");
179 free_ion_mem();
180 return -ENOMEM;
181 }
182
183 return 0;
184}
185
186int allocate_overlay(int fd, GGLSurface gr_fb[])
187{
188 if (!overlay_supported)
189 return -EINVAL;
190
191 struct mdp_overlay overlay;
192 int ret = 0;
193
194 memset(&overlay, 0 , sizeof (struct mdp_overlay));
195
196 /* Fill Overlay Data */
197
198 overlay.src.width = ALIGN(gr_fb[0].width, 32);
199 overlay.src.height = gr_fb[0].height;
200 overlay.src.format = map_mdp_pixel_format();
201 overlay.src_rect.w = gr_fb[0].width;
202 overlay.src_rect.h = gr_fb[0].height;
203 overlay.dst_rect.w = gr_fb[0].width;
204 overlay.dst_rect.h = gr_fb[0].height;
205 overlay.alpha = 0xFF;
206 overlay.transp_mask = MDP_TRANSP_NOP;
207 overlay.id = MSMFB_NEW_REQUEST;
208 ret = ioctl(fd, MSMFB_OVERLAY_SET, &overlay);
209 if (ret < 0) {
210 perror("Overlay Set Failed");
211 return ret;
212 }
213
214 overlay_id = overlay.id;
215 return 0;
216}
217
218int free_overlay(int fd)
219{
220 if (!overlay_supported)
221 return -EINVAL;
222
223 int ret = 0;
224 struct mdp_display_commit ext_commit;
225
226 if (overlay_id != MSMFB_NEW_REQUEST) {
227 ret = ioctl(fd, MSMFB_OVERLAY_UNSET, &overlay_id);
228 if (ret) {
229 perror("Overlay Unset Failed");
230 overlay_id = MSMFB_NEW_REQUEST;
231 return ret;
232 }
233
234 memset(&ext_commit, 0, sizeof(struct mdp_display_commit));
235 ext_commit.flags = MDP_DISPLAY_COMMIT_OVERLAY;
236 ext_commit.wait_for_finish = 1;
237 ret = ioctl(fd, MSMFB_DISPLAY_COMMIT, &ext_commit);
238 if (ret < 0) {
239 perror("ERROR: Clear MSMFB_DISPLAY_COMMIT failed!");
240 overlay_id = MSMFB_NEW_REQUEST;
241 return ret;
242 }
243
244 overlay_id = MSMFB_NEW_REQUEST;
245 }
246 return 0;
247}
248
249int overlay_display_frame(int fd, GGLubyte* data, size_t size)
250{
251 if (!overlay_supported)
252 return -EINVAL;
253 int ret = 0;
254 struct msmfb_overlay_data ovdata;
255 struct mdp_display_commit ext_commit;
256
257 if (overlay_id == MSMFB_NEW_REQUEST) {
258 perror("display_frame failed, no overlay\n");
259 return 0;
260 }
261
262 memcpy(mem_info.mem_buf, data, size);
263
264 memset(&ovdata, 0, sizeof(struct msmfb_overlay_data));
265
266 ovdata.id = overlay_id;
267 ovdata.data.flags = 0;
268 ovdata.data.offset = 0;
269 ovdata.data.memory_id = mem_info.mem_fd;
270 ret = ioctl(fd, MSMFB_OVERLAY_PLAY, &ovdata);
271 if (ret < 0) {
272 perror("overlay_display_frame failed, overlay play Failed\n");
273 return 0;
274 }
275
276 memset(&ext_commit, 0, sizeof(struct mdp_display_commit));
277 ext_commit.flags = MDP_DISPLAY_COMMIT_OVERLAY;
278 ext_commit.wait_for_finish = 1;
279 ret = ioctl(fd, MSMFB_DISPLAY_COMMIT, &ext_commit);
280 if (ret < 0) {
281 perror("overlay_display_frame failed, overlay commit Failed\n!");
282 return 0;
283 }
284
285 return 0;
286}
287
288#else
289
Andrew Doddbb687f42014-06-29 18:24:35 -0400290bool target_has_overlay(char *version) {
291 return false;
292}
293
Dees Troy62b75ab2014-05-02 13:20:33 +0000294int free_ion_mem(void) {
295 return -EINVAL;
296}
297
298int alloc_ion_mem(unsigned int size)
299{
300 return -EINVAL;
301}
302
303int allocate_overlay(int fd, GGLSurface gr_fb[])
304{
305 return -EINVAL;
306}
307
308int free_overlay(int fd)
309{
310 return -EINVAL;
311}
312
313int overlay_display_frame(int fd, GGLubyte* data, size_t size)
314{
315 return -EINVAL;
316}
317
318#endif //#ifdef MSM_BSP