• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Allwinner SoCs display driver.
3  *
4  * Copyright (C) 2016 Allwinner.
5  *
6  * This file is licensed under the terms of the GNU General Public
7  * License version 2.  This program is licensed "as is" without any
8  * warranty of any kind, whether express or implied.
9  */
10 
11 #if defined(CONFIG_DISP2_SUNXI_SUPPORT_ENAHNCE)
12 #include "disp_enhance.h"
13 
14 struct disp_enhance_private_data {
15 	u32 reg_base;
16 	u32 enabled;
17 	bool applied;
18 
19 	struct disp_enhance_config config;
20 
21 	 s32 (*shadow_protect)(u32 sel, bool protect);
22 };
23 static spinlock_t enhance_data_lock;
24 
25 static struct disp_enhance *enhances;
26 static struct disp_enhance_private_data *enhance_private;
27 
disp_get_enhance(u32 disp)28 struct disp_enhance *disp_get_enhance(u32 disp)
29 {
30 	u32 num_screens;
31 
32 	num_screens = bsp_disp_feat_get_num_screens();
33 	if (disp >= num_screens) {
34 		DE_WRN("disp %d out of range\n", disp);
35 		return NULL;
36 	}
37 
38 	return &enhances[disp];
39 }
40 
disp_enhance_get_priv(struct disp_enhance * enhance)41 static struct disp_enhance_private_data *disp_enhance_get_priv(struct
42 							       disp_enhance
43 							       *enhance)
44 {
45 	if (enhance == NULL) {
46 		DE_INF("NULL hdl!\n");
47 		return NULL;
48 	}
49 
50 	return &enhance_private[enhance->disp];
51 }
52 
disp_enhance_sync(struct disp_enhance * enhance)53 static s32 disp_enhance_sync(struct disp_enhance *enhance)
54 {
55 	struct disp_enhance_private_data *enhancep =
56 	    disp_enhance_get_priv(enhance);
57 
58 	if ((enhance == NULL) || (enhancep == NULL)) {
59 		DE_INF("NULL hdl!\n");
60 		return -1;
61 	}
62 
63 	if (disp_feat_is_using_rcq(enhance->disp))
64 		return 0;
65 
66 
67 	enhance->update_regs(enhance);
68 	if (enhancep->enabled)
69 		disp_al_enhance_sync(enhance->disp);
70 
71 	return 0;
72 }
73 
disp_enhance_tasklet(struct disp_enhance * enhance)74 static s32 disp_enhance_tasklet(struct disp_enhance *enhance)
75 {
76 	/* unsigned long flags; */
77 	struct disp_enhance_private_data *enhancep =
78 	    disp_enhance_get_priv(enhance);
79 
80 	if ((enhance == NULL) || (enhancep == NULL)) {
81 		DE_INF("NULL hdl!\n");
82 		return -1;
83 	}
84 
85 	if (enhancep->enabled)
86 		disp_al_enhance_tasklet(enhance->disp);
87 
88 	return 0;
89 }
90 
disp_enhance_update_regs(struct disp_enhance * enhance)91 static s32 disp_enhance_update_regs(struct disp_enhance *enhance)
92 {
93 	unsigned long flags;
94 	struct disp_enhance_private_data *enhancep =
95 	    disp_enhance_get_priv(enhance);
96 
97 	if ((enhance == NULL) || (enhancep == NULL)) {
98 		DE_INF("NULL hdl!\n");
99 		return -1;
100 	}
101 
102 	/* size likely change while it depend on layer size */
103 	/* if (enhancep->applied) { */
104 	{
105 		disp_al_enhance_update_regs(enhance->disp);
106 	}
107 
108 	spin_lock_irqsave(&enhance_data_lock, flags);
109 	enhancep->applied = false;
110 	spin_unlock_irqrestore(&enhance_data_lock, flags);
111 
112 	return 0;
113 }
114 
disp_enhance_apply(struct disp_enhance * enhance)115 static s32 disp_enhance_apply(struct disp_enhance *enhance)
116 {
117 	unsigned long flags;
118 	struct disp_enhance_private_data *enhancep =
119 	    disp_enhance_get_priv(enhance);
120 	struct disp_enhance_config config;
121 
122 	if ((enhance == NULL) || (enhancep == NULL)) {
123 		DE_INF("NULL hdl!\n");
124 		return -1;
125 	}
126 	DE_INF("disp_enhance_apply, screen %d\n", enhance->disp);
127 	memset(&config, 0, sizeof(struct disp_enhance_config));
128 	spin_lock_irqsave(&enhance_data_lock, flags);
129 	if (enhancep->config.flags != 0) {
130 		memcpy(&config, &enhancep->config,
131 		       sizeof(struct disp_enhance_config));
132 		enhancep->applied = true;
133 	}
134 	spin_unlock_irqrestore(&enhance_data_lock, flags);
135 
136 	if (config.flags != ENH_NONE_DIRTY) {
137 		disp_enhance_shadow_protect(enhance, 1);
138 		disp_al_enhance_apply(enhance->disp, &config);
139 		disp_enhance_shadow_protect(enhance, 0);
140 	}
141 
142 	spin_lock_irqsave(&enhance_data_lock, flags);
143 	if (config.flags != 0)
144 		enhancep->applied = true;
145 	config.flags = ENH_NONE_DIRTY;
146 	spin_unlock_irqrestore(&enhance_data_lock, flags);
147 
148 	return 0;
149 }
150 
disp_enhance_force_apply(struct disp_enhance * enhance)151 static s32 disp_enhance_force_apply(struct disp_enhance *enhance)
152 {
153 	unsigned long flags;
154 	struct disp_enhance_private_data *enhancep =
155 	    disp_enhance_get_priv(enhance);
156 	struct disp_device *dispdev = NULL;
157 
158 	if ((enhance == NULL) || (enhancep == NULL)) {
159 		DE_INF("NULL hdl!\n");
160 		return -1;
161 	}
162 	if (enhance->manager)
163 		dispdev = enhance->manager->device;
164 	if (dispdev)
165 		dispdev->get_resolution(dispdev,
166 					&enhancep->config.info.size.width,
167 					&enhancep->config.info.size.height);
168 
169 	spin_lock_irqsave(&enhance_data_lock, flags);
170 	enhancep->config.flags |= ENH_ALL_DIRTY;
171 	spin_unlock_irqrestore(&enhance_data_lock, flags);
172 	disp_enhance_apply(enhance);
173 	disp_enhance_update_regs(enhance);
174 	disp_enhance_sync(enhance);
175 
176 	return 0;
177 }
178 
179 /* seem no meaning */
disp_enhance_is_enabled(struct disp_enhance * enhance)180 static bool disp_enhance_is_enabled(struct disp_enhance *enhance)
181 {
182 	struct disp_enhance_private_data *enhancep =
183 	    disp_enhance_get_priv(enhance);
184 
185 	if ((enhance == NULL) || (enhancep == NULL)) {
186 		DE_INF("NULL hdl!\n");
187 		return false;
188 	}
189 
190 	return enhancep->enabled;
191 }
192 
disp_enhance_enable(struct disp_enhance * enhance)193 static s32 disp_enhance_enable(struct disp_enhance *enhance)
194 {
195 	unsigned long flags;
196 	struct disp_enhance_private_data *enhancep =
197 	    disp_enhance_get_priv(enhance);
198 	struct disp_device *dispdev = NULL;
199 
200 	if ((enhance == NULL) || (enhancep == NULL)) {
201 		DE_INF("NULL hdl!\n");
202 		return -1;
203 	}
204 	if (enhance->manager)
205 		dispdev = enhance->manager->device;
206 	if (dispdev) {
207 		dispdev->get_resolution(dispdev,
208 					&enhancep->config.info.size.width,
209 					&enhancep->config.info.size.height);
210 		if (dispdev->type == DISP_OUTPUT_TYPE_HDMI)
211 			enhancep->config.info.mode = (enhancep->config.info.mode
212 			    & 0xffff0000) | (1);	/* hdmi */
213 		else
214 			enhancep->config.info.mode = (enhancep->config.info.mode
215 			    & 0xffff0000) | (0);	/* lcd */
216 	}
217 
218 	spin_lock_irqsave(&enhance_data_lock, flags);
219 	enhancep->config.info.enable = 1;
220 	enhancep->config.flags |= ENH_ENABLE_DIRTY | ENH_SIZE_DIRTY;
221 
222 	if ((enhancep->config.info.window.width == 0)
223 	    || (enhancep->config.info.window.height == 0)) {
224 		enhancep->config.info.window.width =
225 		    enhancep->config.info.size.width;
226 		enhancep->config.info.window.height =
227 		    enhancep->config.info.size.height;
228 	}
229 
230 	enhancep->enabled = 1;
231 	spin_unlock_irqrestore(&enhance_data_lock, flags);
232 
233 	disp_enhance_apply(enhance);
234 	return 0;
235 }
236 
disp_enhance_disable(struct disp_enhance * enhance)237 static s32 disp_enhance_disable(struct disp_enhance *enhance)
238 {
239 	unsigned long flags;
240 	struct disp_enhance_private_data *enhancep =
241 	    disp_enhance_get_priv(enhance);
242 
243 	if ((enhance == NULL) || (enhancep == NULL)) {
244 		DE_INF("NULL hdl!\n");
245 		return -1;
246 	}
247 
248 	spin_lock_irqsave(&enhance_data_lock, flags);
249 	enhancep->config.info.enable = 0;
250 	enhancep->config.flags |= ENH_ENABLE_DIRTY;
251 
252 	enhancep->enabled = 0;
253 	spin_unlock_irqrestore(&enhance_data_lock, flags);
254 
255 	disp_enhance_apply(enhance);
256 
257 	return 0;
258 }
259 
disp_enhance_demo_enable(struct disp_enhance * enhance)260 static s32 disp_enhance_demo_enable(struct disp_enhance *enhance)
261 {
262 	unsigned long flags;
263 	struct disp_enhance_private_data *enhancep = disp_enhance_get_priv(enhance);
264 
265 	if ((NULL == enhance) || (NULL == enhancep)) {
266 		DE_INF("NULL hdl!\n");
267 		return -1;
268 	}
269 
270 	spin_lock_irqsave(&enhance_data_lock, flags);
271 	enhancep->config.info.demo_enable = 1;
272 	spin_unlock_irqrestore(&enhance_data_lock, flags);
273 
274 	disp_enhance_apply(enhance);
275 	return 0;
276 }
277 
disp_enhance_demo_disable(struct disp_enhance * enhance)278 static s32 disp_enhance_demo_disable(struct disp_enhance *enhance)
279 {
280 	unsigned long flags;
281 	struct disp_enhance_private_data *enhancep = disp_enhance_get_priv(enhance);
282 
283 	if ((NULL == enhance) || (NULL == enhancep)) {
284 		DE_INF("NULL hdl!\n");
285 		return -1;
286 	}
287 
288 	spin_lock_irqsave(&enhance_data_lock, flags);
289 	enhancep->config.info.demo_enable = 0;
290 	spin_unlock_irqrestore(&enhance_data_lock, flags);
291 
292 	disp_enhance_apply(enhance);
293 	return 0;
294 }
295 
disp_enhance_set_mode(struct disp_enhance * enhance,u32 mode)296 static s32 disp_enhance_set_mode(struct disp_enhance *enhance, u32 mode)
297 {
298 	unsigned long flags;
299 	struct disp_enhance_private_data *enhancep = disp_enhance_get_priv(enhance);
300 
301 	if ((NULL == enhance) || (NULL == enhancep)) {
302 		DE_INF("NULL hdl!\n");
303 		return -1;
304 	}
305 
306 	spin_lock_irqsave(&enhance_data_lock, flags);
307 	enhancep->config.info.mode = (enhancep->config.info.mode & 0xffff)  | (mode << 16);
308 	enhancep->config.flags |= ENH_MODE_DIRTY;
309 	spin_unlock_irqrestore(&enhance_data_lock, flags);
310 
311 	disp_enhance_apply(enhance);
312 	return 0;
313 }
314 
disp_enhance_get_mode(struct disp_enhance * enhance)315 static s32 disp_enhance_get_mode(struct disp_enhance *enhance)
316 {
317 	struct disp_enhance_private_data *enhancep = disp_enhance_get_priv(enhance);
318 
319 	if ((NULL == enhance) || (NULL == enhancep)) {
320 		DE_INF("NULL hdl!\n");
321 		return 0;
322 	}
323 
324 	return enhancep->config.info.mode >> 16;
325 }
326 
disp_enhance_set_bright(struct disp_enhance * enhance,u32 value)327 static s32 disp_enhance_set_bright(struct disp_enhance *enhance, u32 value)
328 {
329 	unsigned long flags;
330 	struct disp_enhance_private_data *enhancep =
331 	    disp_enhance_get_priv(enhance);
332 
333 	if ((enhance == NULL) || (enhancep == NULL)) {
334 		DE_INF("NULL hdl!\n");
335 		return -1;
336 	}
337 
338 	spin_lock_irqsave(&enhance_data_lock, flags);
339 	enhancep->config.info.bright = value;
340 	enhancep->config.flags |= ENH_BRIGHT_DIRTY;
341 	spin_unlock_irqrestore(&enhance_data_lock, flags);
342 
343 	disp_enhance_apply(enhance);
344 
345 	return 0;
346 }
347 
disp_enhance_get_bright(struct disp_enhance * enhance)348 static s32 disp_enhance_get_bright(struct disp_enhance *enhance)
349 {
350 	struct disp_enhance_private_data *enhancep =
351 	    disp_enhance_get_priv(enhance);
352 
353 	if ((NULL == enhance) || (NULL == enhancep)) {
354 		DE_INF("NULL hdl!\n");
355 		return 0;
356 	}
357 
358 	return enhancep->config.info.bright;
359 }
360 
disp_enhance_set_saturation(struct disp_enhance * enhance,u32 value)361 static s32 disp_enhance_set_saturation(struct disp_enhance *enhance, u32 value)
362 {
363 	unsigned long flags;
364 	struct disp_enhance_private_data *enhancep =
365 	    disp_enhance_get_priv(enhance);
366 
367 	if ((NULL == enhance) || (NULL == enhancep)) {
368 		DE_INF("NULL hdl!\n");
369 		return -1;
370 	}
371 
372 	spin_lock_irqsave(&enhance_data_lock, flags);
373 	enhancep->config.info.saturation = value;
374 	enhancep->config.flags |= ENH_SAT_DIRTY;
375 	spin_unlock_irqrestore(&enhance_data_lock, flags);
376 
377 	disp_enhance_apply(enhance);
378 	return 0;
379 }
380 
disp_enhance_get_saturation(struct disp_enhance * enhance)381 static s32 disp_enhance_get_saturation(struct disp_enhance *enhance)
382 {
383 	struct disp_enhance_private_data *enhancep =
384 	    disp_enhance_get_priv(enhance);
385 
386 	if ((NULL == enhance) || (NULL == enhancep)) {
387 		DE_INF("NULL hdl!\n");
388 		return 0;
389 	}
390 
391 	return enhancep->config.info.saturation;
392 }
393 
disp_enhance_set_contrast(struct disp_enhance * enhance,u32 value)394 static s32 disp_enhance_set_contrast(struct disp_enhance *enhance, u32 value)
395 {
396 	unsigned long flags;
397 	struct disp_enhance_private_data *enhancep =
398 	    disp_enhance_get_priv(enhance);
399 
400 	if ((NULL == enhance) || (NULL == enhancep)) {
401 		DE_INF("NULL hdl!\n");
402 		return -1;
403 	}
404 
405 	spin_lock_irqsave(&enhance_data_lock, flags);
406 	enhancep->config.info.contrast = value;
407 	enhancep->config.flags |= ENH_CONTRAST_DIRTY;
408 	spin_unlock_irqrestore(&enhance_data_lock, flags);
409 
410 	disp_enhance_apply(enhance);
411 
412 	return 0;
413 }
414 
disp_enhance_get_contrast(struct disp_enhance * enhance)415 static s32 disp_enhance_get_contrast(struct disp_enhance *enhance)
416 {
417 	struct disp_enhance_private_data *enhancep =
418 	    disp_enhance_get_priv(enhance);
419 
420 	if ((NULL == enhance) || (NULL == enhancep)) {
421 		DE_INF("NULL hdl!\n");
422 		return 0;
423 	}
424 
425 	return enhancep->config.info.contrast;
426 }
427 
disp_enhance_set_edge(struct disp_enhance * enhance,u32 value)428 static s32 disp_enhance_set_edge(struct disp_enhance *enhance, u32 value)
429 {
430 	unsigned long flags;
431 	struct disp_enhance_private_data *enhancep =
432 	    disp_enhance_get_priv(enhance);
433 
434 	if ((enhance == NULL) || (enhancep == NULL)) {
435 		DE_INF("NULL hdl!\n");
436 		return -1;
437 	}
438 
439 	spin_lock_irqsave(&enhance_data_lock, flags);
440 	enhancep->config.info.edge = value;
441 	enhancep->config.flags |= ENH_EDGE_DIRTY;
442 	spin_unlock_irqrestore(&enhance_data_lock, flags);
443 
444 	disp_enhance_apply(enhance);
445 
446 	return 0;
447 }
448 
disp_enhance_get_edge(struct disp_enhance * enhance)449 static s32 disp_enhance_get_edge(struct disp_enhance *enhance)
450 {
451 	struct disp_enhance_private_data *enhancep =
452 	    disp_enhance_get_priv(enhance);
453 
454 	if ((NULL == enhance) || (NULL == enhancep)) {
455 		DE_INF("NULL hdl!\n");
456 		return 0;
457 	}
458 
459 	return enhancep->config.info.edge;
460 }
461 
disp_enhance_set_detail(struct disp_enhance * enhance,u32 value)462 static s32 disp_enhance_set_detail(struct disp_enhance *enhance, u32 value)
463 {
464 	unsigned long flags;
465 	struct disp_enhance_private_data *enhancep =
466 	    disp_enhance_get_priv(enhance);
467 
468 	if ((NULL == enhance) || (NULL == enhancep)) {
469 		DE_INF("NULL hdl!\n");
470 		return -1;
471 	}
472 
473 	spin_lock_irqsave(&enhance_data_lock, flags);
474 	enhancep->config.info.detail = value;
475 	enhancep->config.flags |= ENH_DETAIL_DIRTY;
476 	spin_unlock_irqrestore(&enhance_data_lock, flags);
477 
478 	disp_enhance_apply(enhance);
479 
480 	return 0;
481 }
482 
disp_enhance_get_detail(struct disp_enhance * enhance)483 static s32 disp_enhance_get_detail(struct disp_enhance *enhance)
484 {
485 	struct disp_enhance_private_data *enhancep =
486 	    disp_enhance_get_priv(enhance);
487 
488 	if ((enhance == NULL) || (enhancep == NULL)) {
489 		DE_INF("NULL hdl!\n");
490 		return 0;
491 	}
492 
493 	return enhancep->config.info.detail;
494 }
495 
disp_enhance_set_denoise(struct disp_enhance * enhance,u32 value)496 static s32 disp_enhance_set_denoise(struct disp_enhance *enhance, u32 value)
497 {
498 	unsigned long flags;
499 	struct disp_enhance_private_data *enhancep =
500 	    disp_enhance_get_priv(enhance);
501 
502 	if ((NULL == enhance) || (NULL == enhancep)) {
503 		DE_INF("NULL hdl!\n");
504 		return -1;
505 	}
506 
507 	spin_lock_irqsave(&enhance_data_lock, flags);
508 	enhancep->config.info.denoise = value;
509 	enhancep->config.flags |= ENH_DNS_DIRTY;
510 	spin_unlock_irqrestore(&enhance_data_lock, flags);
511 
512 	disp_enhance_apply(enhance);
513 
514 	return 0;
515 }
516 
disp_enhance_get_denoise(struct disp_enhance * enhance)517 static s32 disp_enhance_get_denoise(struct disp_enhance *enhance)
518 {
519 	struct disp_enhance_private_data *enhancep =
520 	    disp_enhance_get_priv(enhance);
521 
522 	if ((NULL == enhance) || (NULL == enhancep)) {
523 		DE_INF("NULL hdl!\n");
524 		return 0;
525 	}
526 
527 	return enhancep->config.info.denoise;
528 }
529 
disp_enhance_set_manager(struct disp_enhance * enhance,struct disp_manager * mgr)530 static s32 disp_enhance_set_manager(struct disp_enhance *enhance,
531 				    struct disp_manager *mgr)
532 {
533 	unsigned long flags;
534 
535 	if ((enhance == NULL) || (mgr == NULL)) {
536 		DE_INF("NULL hdl!\n");
537 		return -1;
538 	}
539 
540 	spin_lock_irqsave(&enhance_data_lock, flags);
541 	enhance->manager = mgr;
542 	mgr->enhance = enhance;
543 	spin_unlock_irqrestore(&enhance_data_lock, flags);
544 
545 	return 0;
546 }
547 
disp_enhance_unset_manager(struct disp_enhance * enhance)548 static s32 disp_enhance_unset_manager(struct disp_enhance *enhance)
549 {
550 	unsigned long flags;
551 
552 	if (enhance == NULL) {
553 		DE_INF("NULL hdl!\n");
554 		return -1;
555 	}
556 
557 	spin_lock_irqsave(&enhance_data_lock, flags);
558 	if (enhance->manager)
559 		enhance->manager->enhance = NULL;
560 	enhance->manager = NULL;
561 	spin_unlock_irqrestore(&enhance_data_lock, flags);
562 
563 	return 0;
564 }
565 
disp_enhance_shadow_protect(struct disp_enhance * enhance,bool protect)566 static s32 disp_enhance_shadow_protect(struct disp_enhance *enhance,
567 				       bool protect)
568 {
569 	struct disp_enhance_private_data *enhancep =
570 	    disp_enhance_get_priv(enhance);
571 
572 	if ((enhance == NULL) || (enhancep == NULL)) {
573 		DE_INF("NULL hdl!\n");
574 		return -1;
575 	}
576 
577 	if (enhancep->shadow_protect)
578 		return enhancep->shadow_protect(enhance->disp, protect);
579 
580 	return -1;
581 }
582 
disp_enhance_dump(struct disp_enhance * enhance,char * buf)583 static s32 disp_enhance_dump(struct disp_enhance *enhance, char *buf)
584 {
585 	struct disp_enhance_config config;
586 	struct disp_enhance_private_data *enhancep =
587 	    disp_enhance_get_priv(enhance);
588 	u32 count = 0;
589 
590 	if ((enhance == NULL) || (enhancep == NULL)) {
591 		DE_INF("NULL hdl!\n");
592 		return -1;
593 	}
594 
595 	memcpy(&config, &enhancep->config, sizeof(struct disp_enhance_config));
596 
597 	count += sprintf(buf + count, "enhance %d: %s, %s\n",
598 			 enhance->disp,
599 			 (config.info.enable == 1) ? "enable" : "disable",
600 			 (config.info.demo_enable == 1) ? "demo" : "normal");
601 
602 	return count;
603 }
604 
disp_enhance_init(struct disp_enhance * enhance)605 static s32 disp_enhance_init(struct disp_enhance *enhance)
606 {
607 	struct disp_enhance_private_data *enhancep =
608 	    disp_enhance_get_priv(enhance);
609 
610 	if ((enhance == NULL) || (enhancep == NULL)) {
611 		DE_INF("NULL hdl!\n");
612 		return -1;
613 	}
614 
615 	return 0;
616 }
617 
disp_enhance_exit(struct disp_enhance * enhance)618 static s32 disp_enhance_exit(struct disp_enhance *enhance)
619 {
620 	struct disp_enhance_private_data *enhancep =
621 	    disp_enhance_get_priv(enhance);
622 
623 	if ((enhance == NULL) || (enhancep == NULL)) {
624 		DE_INF("NULL hdl!\n");
625 		return -1;
626 	}
627 
628 	return 0;
629 }
630 
631 /* for inner debug */
disp_enhance_set_para(struct disp_enhance * enhance,struct disp_enhance_para * para)632 s32 disp_enhance_set_para(struct disp_enhance *enhance,
633 			  struct disp_enhance_para *para)
634 {
635 	unsigned long flags;
636 	struct disp_enhance_private_data *enhancep =
637 	    disp_enhance_get_priv(enhance);
638 	struct disp_device *dispdev = NULL;
639 
640 	if ((enhance == NULL) || (enhancep == NULL)) {
641 		DE_INF("NULL hdl!\n");
642 		return -1;
643 	}
644 	if (enhance->manager)
645 		dispdev = enhance->manager->device;
646 	if (dispdev)
647 		dispdev->get_resolution(dispdev,
648 					&enhancep->config.info.size.width,
649 					&enhancep->config.info.size.height);
650 
651 	spin_lock_irqsave(&enhance_data_lock, flags);
652 	memcpy(&enhancep->config.info.window, &para->window,
653 	       sizeof(struct disp_rect));
654 	enhancep->config.info.enable = para->enable;
655 	enhancep->config.flags |= ENH_ENABLE_DIRTY | ENH_SIZE_DIRTY;
656 
657 	if ((enhancep->config.info.window.width == 0)
658 	    || (enhancep->config.info.window.height == 0)) {
659 		enhancep->config.info.window.width =
660 		    enhancep->config.info.size.width;
661 		enhancep->config.info.window.height =
662 		    enhancep->config.info.size.height;
663 	}
664 
665 	enhancep->config.info.bright = para->bright;
666 	enhancep->config.info.contrast = para->contrast;
667 	enhancep->config.info.saturation = para->saturation;
668 	enhancep->config.info.hue = para->hue;
669 	enhancep->config.info.sharp = para->sharp;
670 	enhancep->config.info.auto_contrast = para->auto_contrast;
671 
672 	enhancep->config.info.auto_color = para->auto_color;
673 	enhancep->config.info.fancycolor_red = para->fancycolor_red;
674 	enhancep->config.info.fancycolor_blue = para->fancycolor_blue;
675 	enhancep->config.info.fancycolor_green = para->fancycolor_green;
676 
677 	enhancep->enabled = para->enable;
678 	spin_unlock_irqrestore(&enhance_data_lock, flags);
679 	DE_INF
680 	    ("en=%d,para=%d,%d,%d,%d,sharp=%d,auto=%d,%d,fancycolor=%d,%d,%d\n",
681 	     enhancep->config.info.enable, enhancep->config.info.bright,
682 	     enhancep->config.info.contrast, enhancep->config.info.saturation,
683 	     enhancep->config.info.hue, enhancep->config.info.sharp,
684 	     enhancep->config.info.auto_color,
685 	     enhancep->config.info.auto_contrast,
686 	     enhancep->config.info.fancycolor_red,
687 	     enhancep->config.info.fancycolor_green,
688 	     enhancep->config.info.fancycolor_blue);
689 
690 	disp_enhance_apply(enhance);
691 	return 0;
692 }
693 
disp_init_enhance(struct disp_bsp_init_para * para)694 s32 disp_init_enhance(struct disp_bsp_init_para *para)
695 {
696 	u32 num_enhances;
697 	u32 disp;
698 	struct disp_enhance *enhance;
699 	struct disp_enhance_private_data *enhancep;
700 
701 	DE_INF("disp_init_enhance\n");
702 
703 	spin_lock_init(&enhance_data_lock);
704 	num_enhances = bsp_disp_feat_get_num_screens();
705 	enhances =
706 	    kmalloc_array(num_enhances, sizeof(struct disp_enhance),
707 			  GFP_KERNEL | __GFP_ZERO);
708 	if (enhances == NULL) {
709 		DE_WRN("malloc memory fail!\n");
710 		goto malloc_err;
711 	}
712 	enhance_private =
713 	    (struct disp_enhance_private_data *)
714 	    kmalloc(sizeof(struct disp_enhance_private_data)
715 		    * num_enhances, GFP_KERNEL | __GFP_ZERO);
716 	if (enhance_private == NULL) {
717 		DE_WRN("malloc memory fail!\n");
718 		goto malloc_err;
719 	}
720 
721 	for (disp = 0; disp < num_enhances; disp++) {
722 		if (bsp_disp_feat_is_support_enhance(disp) == 0)
723 			continue;
724 
725 		enhance = &enhances[disp];
726 		enhancep = &enhance_private[disp];
727 
728 		switch (disp) {
729 		case 0:
730 			enhance->name = "enhance0";
731 			enhance->disp = 0;
732 			break;
733 		case 1:
734 			enhance->name = "enhance1";
735 			enhance->disp = 1;
736 			break;
737 		case 2:
738 			enhance->name = "enhance2";
739 			enhance->disp = 2;
740 
741 			break;
742 		}
743 		enhancep->shadow_protect = para->shadow_protect;
744 
745 		enhance->enable = disp_enhance_enable;
746 		enhance->disable = disp_enhance_disable;
747 		enhance->is_enabled = disp_enhance_is_enabled;
748 		enhance->init = disp_enhance_init;
749 		enhance->exit = disp_enhance_exit;
750 		enhance->apply = disp_enhance_apply;
751 		enhance->update_regs = disp_enhance_update_regs;
752 		enhance->force_apply = disp_enhance_force_apply;
753 		enhance->sync = disp_enhance_sync;
754 		enhance->tasklet = disp_enhance_tasklet;
755 		enhance->set_manager = disp_enhance_set_manager;
756 		enhance->unset_manager = disp_enhance_unset_manager;
757 		enhance->set_para = disp_enhance_set_para;
758 		enhance->dump = disp_enhance_dump;
759 		enhance->demo_enable = disp_enhance_demo_enable;
760 		enhance->demo_disable = disp_enhance_demo_disable;
761 		enhance->set_mode = disp_enhance_set_mode;
762 		enhance->get_mode = disp_enhance_get_mode;
763 		enhance->set_bright = disp_enhance_set_bright;
764 		enhance->get_bright = disp_enhance_get_bright;
765 		enhance->set_saturation = disp_enhance_set_saturation;
766 		enhance->get_saturation = disp_enhance_get_saturation;
767 		enhance->set_contrast = disp_enhance_set_contrast;
768 		enhance->get_contrast = disp_enhance_get_contrast;
769 		enhance->set_edge = disp_enhance_set_edge;
770 		enhance->get_edge = disp_enhance_get_edge;
771 		enhance->set_detail = disp_enhance_set_detail;
772 		enhance->get_detail = disp_enhance_get_detail;
773 		enhance->set_denoise = disp_enhance_set_denoise;
774 		enhance->get_denoise = disp_enhance_get_denoise;
775 
776 		enhance->init(enhance);
777 	}
778 
779 	return 0;
780 malloc_err:
781 	kfree(enhance_private);
782 	kfree(enhances);
783 	enhance_private = NULL;
784 	enhances = NULL;
785 
786 	return -1;
787 }
788 
disp_exit_enhance(void)789 s32 disp_exit_enhance(void)
790 {
791 	u32 num_enhances;
792 	u32 disp;
793 	struct disp_enhance *enhance;
794 
795 	if (!enhances)
796 		return 0;
797 
798 	num_enhances = bsp_disp_feat_get_num_screens();
799 	for (disp = 0; disp < num_enhances; disp++) {
800 		if (bsp_disp_feat_is_support_enhance(disp) == 0)
801 			continue;
802 
803 		enhance = &enhances[disp];
804 		enhance->exit(enhance);
805 	}
806 
807 	kfree(enhance_private);
808 	kfree(enhances);
809 
810 	return 0;
811 }
812 
813 #endif
814