• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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