1 /*
2 * Copyright (C) 2015 Allwinnertech, z.q <zengqi@allwinnertech.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 */
9
10 #include"disp_eink.h"
11
12 #ifdef SUPPORT_EINK
13 #include "include.h"
14 #include "disp_private.h"
15
16 /* #define BUFFER_SAVE_BACK */
17
18 #ifdef BUFFER_SAVE_BACK
19 #if 0
20 static s32 __clean_ring_queue(struct eink_buffer_manager *buffer_mgr)
21 {
22 int i;
23 unsigned int buf_size;
24
25 buf_size = buffer_mgr->buf_size;
26
27 for (i = 0; i < IMAGE_BUF_NUM; i++)
28 disp_free((void *)buffer_mgr->image_slot[i].vaddr,
29 (void *)buffer_mgr->image_slot[i].paddr, buf_size);
30
31 return 0;
32 }
33 #endif
__save_buf2storg(__u8 * buf,char * file_name,__u32 length,loff_t pos)34 static int __save_buf2storg(__u8 *buf, char *file_name, __u32 length,
35 loff_t pos)
36 {
37 struct file *fp = NULL;
38 mm_segment_t old_fs;
39 ssize_t ret = 0;
40
41 if ((buf == NULL) || (file_name == NULL)) {
42 __debug(KERN_ALERT "%s: buf or file_name is null\n", __func__);
43 return -1;
44 }
45
46 fp = filp_open(file_name, O_RDWR | O_CREAT, 0644);
47 if (IS_ERR(fp)) {
48 __debug(KERN_ALERT "%s: fail to open file(%s), ret=%d\n",
49 __func__, file_name, (u32) fp);
50 return -1;
51 }
52
53 old_fs = get_fs();
54 set_fs(KERNEL_DS);
55
56 ret = vfs_write(fp, buf, length, &pos);
57 __debug(KERN_ALERT "%s: save %s done, len=%d, pos=%lld, ret=%d\n",
58 __func__, file_name, length, pos, ret);
59
60 set_fs(old_fs);
61 filp_close(fp, NULL);
62
63 return ret;
64
65 }
__put_gary2buf(__u8 * buf,char * file_name,__u32 length,loff_t pos)66 int __put_gary2buf(__u8 *buf, char *file_name, __u32 length, loff_t pos)
67 {
68 struct file *fp = NULL;
69 mm_segment_t fs;
70 __s32 read_len = 0;
71 ssize_t ret = 0;
72
73 if ((buf == NULL) || (file_name == NULL)) {
74 __debug(KERN_ALERT "%s: buf or file_name is null\n", __func__);
75 return -1;
76 }
77
78 fp = filp_open(file_name, O_RDONLY, 0);
79 if (IS_ERR(fp)) {
80 pr_err("%s: fail to open file(%s), ret=%d\n",
81 __func__, file_name, (u32)fp);
82 return -1;
83 }
84 fs = get_fs();
85 set_fs(KERNEL_DS);
86
87 read_len = vfs_read(fp, buf, length, &pos);
88 if (read_len != length) {
89 pr_err("maybe miss some data(read=%d byte, file=%d byte)\n",
90 read_len, length);
91 ret = -EAGAIN;
92 }
93 set_fs(fs);
94 filp_close(fp, NULL);
95
96 return ret;
97
98 }
99 #endif
100
__clear_ring_queue_image(struct eink_buffer_manager * buffer_mgr)101 s32 __clear_ring_queue_image(struct eink_buffer_manager *buffer_mgr)
102 {
103 int ret = 0, i = 0;
104
105 mutex_lock(&buffer_mgr->mlock);
106
107 for (i = 0; i < IMAGE_BUF_NUM; i++) {
108 /* init mode need buf data 0xff */
109 memset((void *)buffer_mgr->image_slot[i].vaddr,
110 0xff, buffer_mgr->buf_size);
111 }
112
113 mutex_unlock(&buffer_mgr->mlock);
114
115 return ret;
116 }
117
__is_ring_queue_full(struct eink_buffer_manager * buffer_mgr)118 bool __is_ring_queue_full(struct eink_buffer_manager *buffer_mgr)
119 {
120 bool ret;
121 unsigned int in_index, out_index;
122
123 mutex_lock(&buffer_mgr->mlock);
124
125 in_index = buffer_mgr->in_index;
126 out_index = buffer_mgr->out_index;
127 ret = ((in_index + 1) % IMAGE_BUF_NUM == out_index) ? true : false;
128
129 mutex_unlock(&buffer_mgr->mlock);
130
131 return ret;
132 }
133
__is_ring_queue_empty(struct eink_buffer_manager * buffer_mgr)134 bool __is_ring_queue_empty(struct eink_buffer_manager *buffer_mgr)
135 {
136 bool ret;
137 unsigned int in_index, out_index;
138
139 mutex_lock(&buffer_mgr->mlock);
140
141 in_index = buffer_mgr->in_index;
142 out_index = buffer_mgr->out_index;
143 ret = (in_index == (out_index + 1) % IMAGE_BUF_NUM) ? true : false;
144
145 mutex_unlock(&buffer_mgr->mlock);
146
147 return ret;
148 }
149
__get_current_image(struct eink_buffer_manager * buffer_mgr)150 struct eink_8bpp_image *__get_current_image(struct eink_buffer_manager
151 *buffer_mgr)
152 {
153 struct eink_8bpp_image *ret;
154 unsigned int out_index;
155
156 mutex_lock(&buffer_mgr->mlock);
157
158 out_index = buffer_mgr->out_index;
159 if (out_index < IMAGE_BUF_NUM) {
160 ret = &buffer_mgr->image_slot[(out_index + 1) % IMAGE_BUF_NUM];
161 goto out;
162 } else {
163 __wrn("%s: in_index larger than the max value!\n", __func__);
164 ret = NULL;
165 goto out;
166 }
167
168 out:
169 mutex_unlock(&buffer_mgr->mlock);
170
171 return ret;
172 }
173
__get_last_image(struct eink_buffer_manager * buffer_mgr)174 struct eink_8bpp_image *__get_last_image(struct eink_buffer_manager *buffer_mgr)
175 {
176 struct eink_8bpp_image *ret;
177 unsigned int out_index;
178
179 mutex_lock(&buffer_mgr->mlock);
180
181 out_index = buffer_mgr->out_index;
182 if (out_index < IMAGE_BUF_NUM) {
183 ret = &buffer_mgr->image_slot[out_index];
184 goto out;
185 } else {
186 __wrn("%s: in_index larger than the max value!\n", __func__);
187 ret = NULL;
188 goto out;
189 }
190
191 out:
192 mutex_unlock(&buffer_mgr->mlock);
193
194 return ret;
195 }
196
197 #if !defined(SUPPORT_WB)
__conver_32bit_bmp_to_8bit(u8 * src_image_data,u32 width,u32 height,u8 * dest_image_data)198 static int __conver_32bit_bmp_to_8bit(u8 *src_image_data, u32 width,
199 u32 height, u8 *dest_image_data)
200 {
201 struct st_argb *tmp_src_data = NULL;
202 u8 *tmp_dest_data = NULL;
203 u32 wi = 0, hi = 0, co = 0;
204
205 if ((src_image_data == NULL) || (dest_image_data == NULL)) {
206 __wrn("%s: input param is null\n", __func__);
207 return -1;
208 }
209
210 tmp_dest_data = (u8 *) dest_image_data;
211 hi = height;
212 while (hi > 0) {
213 tmp_src_data =
214 (struct st_argb *)src_image_data + (height - hi) * width;
215 for (wi = 0; wi < width; wi++) {
216 *tmp_dest_data = (306 * tmp_src_data->red +
217 601 * tmp_src_data->green +
218 117 * tmp_src_data->blue +
219 0x200) >> 10;
220 tmp_dest_data++;
221 tmp_src_data++;
222 co++;
223 }
224 hi--;
225 }
226 __debug("%s: size = %u.\n", __func__, co);
227
228 return 0;
229 }
230 #endif
231
__queue_image(struct eink_buffer_manager * buffer_mgr,struct disp_layer_config_inner * config,unsigned int layer_num,u32 mode,struct area_info update_area)232 s32 __queue_image(struct eink_buffer_manager *buffer_mgr,
233 struct disp_layer_config_inner *config,
234 unsigned int layer_num,
235 u32 mode, struct area_info update_area)
236 {
237 bool queue_is_full;
238 int ret = 0;
239 unsigned int in_index, out_index;
240 unsigned int buf_size;
241 #ifndef SUPPORT_WB
242 u8 *src_image;
243 #endif
244 #ifdef SUPPORT_WB
245 struct format_manager *cmgr;
246 struct image_format src, dest;
247 #endif
248
249 mutex_lock(&buffer_mgr->mlock);
250
251 in_index = buffer_mgr->in_index;
252 out_index = buffer_mgr->out_index;
253 buf_size = buffer_mgr->buf_size;
254
255 if (in_index >= IMAGE_BUF_NUM) {
256 __wrn("in_index larger than the max value!\n");
257 ret = -EINVAL;
258 goto out;
259 }
260
261 queue_is_full =
262 ((in_index + 1) % IMAGE_BUF_NUM == out_index) ? true : false;
263 /* when last image is missed ,it need cover last image */
264
265 if (queue_is_full) {
266 if (in_index)
267 in_index--;
268 else
269 in_index = IMAGE_BUF_NUM - 1;
270 }
271 #ifdef SUPPORT_WB
272 cmgr = disp_get_format_manager(0);
273 memset((void *)&src, 0, sizeof(struct image_format));
274 src.format = DISP_FORMAT_ARGB_8888;
275 src.width = buffer_mgr->width;
276 src.height = buffer_mgr->height;
277
278 memset((void *)&dest, 0, sizeof(struct image_format));
279 dest.format = DISP_FORMAT_8BIT_GRAY;
280 dest.addr1 = (unsigned long)buffer_mgr->image_slot[in_index].paddr;
281 dest.width = buffer_mgr->width;
282 dest.height = buffer_mgr->height;
283
284 /*start convert*/
285 if (config != NULL)/*config regs*/
286 ret = cmgr->start_convert(0, config, layer_num, &dest);
287 #ifdef BUFFER_SAVE_BACK
288 __save_buf2storg((void *)buffer_mgr->image_slot[in_index].vaddr,
289 "./dst_eink_image.bin",
290 buffer_mgr->width * buffer_mgr->height, 0);
291 #endif
292 if (ret)
293 goto out;
294 #else
295 if (src_image != NULL)
296 __conver_32bit_bmp_to_8bit(src_image, buffer_mgr->width,
297 buffer_mgr->height,
298 (void *)buffer_mgr->
299 image_slot[in_index].vaddr);
300
301 __put_gary2buf((void *)buffer_mgr->image_slot[in_index].vaddr,
302 "./system/eink_image.bin",
303 buffer_mgr->width * buffer_mgr->height, 0);
304 #ifdef BUFFER_SAVE_BACK
305 __save_buf2storg((void *)buffer_mgr->image_slot[in_index].vaddr,
306 "./eink_image.bin",
307 buffer_mgr->width * buffer_mgr->height, 0);
308 #endif
309
310 #endif /* endif SUPPORT_WB */
311 __debug
312 ("%s: index =%d, vaddr=%p, paddr=%p, xt=%d, yt=%d, xb=%d, yb=%d\n",
313 __func__, in_index, buffer_mgr->image_slot[in_index].vaddr,
314 buffer_mgr->image_slot[in_index].paddr, update_area.x_top,
315 update_area.y_top, update_area.x_bottom, update_area.y_bottom);
316 /*
317 * update new 8bpp image information
318 */
319 buffer_mgr->image_slot[in_index].state = USED;
320 buffer_mgr->image_slot[in_index].update_mode = mode;
321 buffer_mgr->image_slot[in_index].window_calc_enable = false;
322
323 if (mode & EINK_RECT_MODE) {
324 buffer_mgr->image_slot[in_index].flash_mode = LOCAL;
325
326 if ((update_area.x_bottom == 0) && (update_area.x_top == 0) &&
327 (update_area.y_bottom == 0) && (update_area.y_top == 0)) {
328 buffer_mgr->image_slot[in_index].window_calc_enable =
329 true;
330 memset(&buffer_mgr->image_slot[in_index].update_area, 0,
331 sizeof(struct area_info));
332 } else {
333 memcpy(&buffer_mgr->image_slot[in_index].update_area,
334 &update_area, sizeof(struct area_info));
335 }
336 } else {
337 if (mode == EINK_INIT_MODE)
338 buffer_mgr->image_slot[in_index].flash_mode = INIT;
339 else
340 buffer_mgr->image_slot[in_index].flash_mode = GLOBAL;
341
342 /* set update area full screen. */
343 buffer_mgr->image_slot[in_index].update_area.x_top = 0;
344 buffer_mgr->image_slot[in_index].update_area.y_top = 0;
345 buffer_mgr->image_slot[in_index].update_area.x_bottom =
346 buffer_mgr->image_slot[in_index].size.width - 1;
347 buffer_mgr->image_slot[in_index].update_area.y_bottom =
348 buffer_mgr->image_slot[in_index].size.height - 1;
349 }
350
351 /*
352 * if queue is full,then cover the newest image,
353 * and in_index keep the same value.
354 */
355 if (!queue_is_full)
356 buffer_mgr->in_index =
357 (buffer_mgr->in_index + 1) % IMAGE_BUF_NUM;
358
359 out:
360 __debug("q:in_index:%d, out_index:%d,paddr:0x%p, wcalc_en=%d\n",
361 buffer_mgr->in_index, buffer_mgr->out_index,
362 buffer_mgr->image_slot[in_index].paddr,
363 buffer_mgr->image_slot[in_index].window_calc_enable);
364
365 mutex_unlock(&buffer_mgr->mlock);
366
367 return ret;
368 }
369
__dequeue_image(struct eink_buffer_manager * buffer_mgr)370 s32 __dequeue_image(struct eink_buffer_manager *buffer_mgr)
371 {
372 bool queue_is_empty;
373 int ret = 0;
374 unsigned int in_index, out_index;
375
376 mutex_lock(&buffer_mgr->mlock);
377 in_index = buffer_mgr->in_index;
378 out_index = buffer_mgr->out_index;
379
380 if (out_index >= IMAGE_BUF_NUM) {
381 __wrn("%s: out_index larger than the max value!\n", __func__);
382 ret = -EINVAL;
383 goto out;
384 }
385
386 queue_is_empty =
387 (in_index == (out_index + 1) % IMAGE_BUF_NUM) ? true : false;
388 if (queue_is_empty) {
389 ret = -EBUSY;
390 __debug("queue is empty!\n");
391 goto out;
392 }
393
394 /*set the 8pp image information to initial state. */
395 buffer_mgr->image_slot[out_index].state = FREE;
396 buffer_mgr->image_slot[out_index].flash_mode = GLOBAL;
397 buffer_mgr->image_slot[out_index].update_mode = EINK_INIT_MODE;
398 buffer_mgr->image_slot[out_index].window_calc_enable = true;
399 buffer_mgr->out_index = (buffer_mgr->out_index + 1) % IMAGE_BUF_NUM;
400
401 __debug("dq in_index:%d, out_index:%d\n", buffer_mgr->in_index,
402 buffer_mgr->out_index);
403 out:
404 mutex_unlock(&buffer_mgr->mlock);
405
406 return ret;
407 }
408
ring_buffer_manager_init(struct disp_eink_manager * eink_manager)409 s32 ring_buffer_manager_init(struct disp_eink_manager *eink_manager)
410 {
411 int i;
412 int ret = 0;
413 struct eink_buffer_manager *buffer_mgr = NULL;
414
415 buffer_mgr =
416 (struct eink_buffer_manager *)disp_sys_malloc(
417 sizeof(struct eink_buffer_manager));
418 if (!buffer_mgr) {
419 __wrn("malloc eink buffer manager memory fail!\n");
420 ret = -ENOMEM;
421 goto buffer_mgr_err;
422 }
423
424 /*
425 * init in_index is 1,ring buffer is empty.
426 * out_index is 0,point to last image.
427 */
428 memset((void *)(buffer_mgr), 0, sizeof(struct eink_buffer_manager));
429 buffer_mgr->width = eink_manager->private_data->param.timing.width;
430 buffer_mgr->height = eink_manager->private_data->param.timing.height;
431 buffer_mgr->buf_size = buffer_mgr->width * buffer_mgr->height;
432 buffer_mgr->in_index = 1;
433 buffer_mgr->out_index = 0;
434 mutex_init(&buffer_mgr->mlock);
435
436 for (i = 0; i < IMAGE_BUF_NUM; i++) {
437 buffer_mgr->image_slot[i].size.width = buffer_mgr->width;
438 buffer_mgr->image_slot[i].size.height = buffer_mgr->height;
439 /* fix it to match different drawer. */
440 buffer_mgr->image_slot[i].size.align = 4;
441 buffer_mgr->image_slot[i].update_mode = EINK_INIT_MODE;
442 buffer_mgr->image_slot[i].vaddr =
443 disp_malloc(buffer_mgr->buf_size,
444 &buffer_mgr->image_slot[i].paddr);
445 if (!buffer_mgr->image_slot[i].vaddr) {
446 __wrn("malloc image buffer memory fail!\n");
447 ret = -ENOMEM;
448 goto image_buffer_err;
449 }
450 __debug("image paddr%d=0x%p", i,
451 buffer_mgr->image_slot[i].paddr);
452
453 /* init mode need buf data 0xff */
454 memset((void *)buffer_mgr->image_slot[i].vaddr, 0xff,
455 buffer_mgr->buf_size);
456 }
457
458 buffer_mgr->is_full = __is_ring_queue_full;
459 buffer_mgr->is_empty = __is_ring_queue_empty;
460 buffer_mgr->get_last_image = __get_last_image;
461 buffer_mgr->get_current_image = __get_current_image;
462 buffer_mgr->queue_image = __queue_image;
463 buffer_mgr->dequeue_image = __dequeue_image;
464 buffer_mgr->clear_image = __clear_ring_queue_image;
465 eink_manager->buffer_mgr = buffer_mgr;
466
467 return ret;
468
469 image_buffer_err:
470 for (i = 0; i < IMAGE_BUF_NUM; i++) {
471 if (buffer_mgr->image_slot[i].vaddr)
472 disp_free(buffer_mgr->image_slot[i].vaddr,
473 (void *)buffer_mgr->image_slot[i].paddr,
474 buffer_mgr->buf_size);
475 }
476
477 buffer_mgr_err:
478 kfree(buffer_mgr);
479
480 return ret;
481 }
482
ring_buffer_manager_exit(struct disp_eink_manager * eink_manager)483 s32 ring_buffer_manager_exit(struct disp_eink_manager *eink_manager)
484 {
485 int i;
486 struct eink_buffer_manager *buffer_mgr = NULL;
487
488 buffer_mgr = eink_manager->buffer_mgr;
489 for (i = 0; i < IMAGE_BUF_NUM; i++) {
490 if (buffer_mgr->image_slot[i].vaddr)
491 disp_free(buffer_mgr->image_slot[i].vaddr,
492 (void *)buffer_mgr->image_slot[i].paddr,
493 buffer_mgr->buf_size);
494 }
495
496 kfree(buffer_mgr);
497 eink_manager->buffer_mgr = NULL;
498
499 return 0;
500 }
501 #endif
502
503