• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 Allwinnertech Co.Ltd
3  * Authors: zhengwanyu
4  *
5  * This program is free software; you can redistribute  it and/or modify it
6  * under  the terms of  the GNU General  Public License as published by the
7  * Free Software Foundation;  either version 2 of the  License, or (at your
8  * option) any later version.
9  *
10  */
11 #include <linux/dma-mapping.h>
12 #include <uapi/drm/drm_fourcc.h>
13 #include <linux/clk.h>
14 
15 #include "sunxi_de.h"
16 
17 #ifdef CONFIG_AW_DRM_DE_V33X
18 #include "disp_al_de.h"
19 #include "de330/de_rtmx.h"
20 #include "de330/de_enhance.h"
21 #include "de330/de_smbl.h"
22 #include "de330/de_wb.h"
23 #include "de330/de_bld.h"
24 #include "de330/de_ccsc.h"
25 
26 #include "tcon/de_lcd.h"
27 #include "tcon/de_dsi.h"
28 #else
29 #include "de_feat.h"
30 #include "de_hal.h"
31 #include "de_clock.h"
32 #include "disp_al.h"
33 #include "de_lcd.h"
34 #include "de_dsi.h"
35 #endif
36 
37 #include "sunxi_common.h"
38 #include "sunxi_tcon.h"
39 
40 static struct sunxi_de_drv *de_drv;
41 
42 #if defined(CONFIG_AW_IOMMU)
43 #define DE_MASTOR_ID 0
44 extern void sunxi_enable_device_iommu(unsigned int mastor_id, bool flag);
45 #endif
46 
47 static const unsigned int ui_layer_formats[] = {
48 	DRM_FORMAT_RGB888,
49 	DRM_FORMAT_BGR888,
50 
51 	DRM_FORMAT_ARGB8888,
52 	DRM_FORMAT_ABGR8888,
53 	DRM_FORMAT_RGBA8888,
54 	DRM_FORMAT_BGRA8888,
55 
56 	DRM_FORMAT_XRGB8888,
57 	DRM_FORMAT_XBGR8888,
58 	DRM_FORMAT_RGBX8888,
59 	DRM_FORMAT_BGRX8888,
60 
61 	DRM_FORMAT_RGB565,
62 	DRM_FORMAT_BGR565,
63 
64 	DRM_FORMAT_ARGB4444,
65 	DRM_FORMAT_ABGR4444,
66 	DRM_FORMAT_RGBA4444,
67 	DRM_FORMAT_BGRA4444,
68 
69 	DRM_FORMAT_ARGB1555,
70 	DRM_FORMAT_ABGR1555,
71 	DRM_FORMAT_RGBA5551,
72 	DRM_FORMAT_BGRA5551,
73 };
74 
75 static const unsigned int vi_layer_formats[] = {
76 	DRM_FORMAT_RGB888,
77 	DRM_FORMAT_BGR888,
78 
79 	DRM_FORMAT_ARGB8888,
80 	DRM_FORMAT_ABGR8888,
81 	DRM_FORMAT_RGBA8888,
82 	DRM_FORMAT_BGRA8888,
83 
84 	DRM_FORMAT_XRGB8888,
85 	DRM_FORMAT_XBGR8888,
86 	DRM_FORMAT_RGBX8888,
87 	DRM_FORMAT_BGRX8888,
88 
89 	DRM_FORMAT_RGB565,
90 	DRM_FORMAT_BGR565,
91 
92 	DRM_FORMAT_ARGB4444,
93 	DRM_FORMAT_ABGR4444,
94 	DRM_FORMAT_RGBA4444,
95 	DRM_FORMAT_BGRA4444,
96 
97 	DRM_FORMAT_ARGB1555,
98 	DRM_FORMAT_ABGR1555,
99 	DRM_FORMAT_RGBA5551,
100 	DRM_FORMAT_BGRA5551,
101 
102 	DRM_FORMAT_AYUV,
103 	DRM_FORMAT_YUV444,
104 	DRM_FORMAT_YUV422,
105 	DRM_FORMAT_YUV420,
106 	DRM_FORMAT_YUV411,
107 
108 	DRM_FORMAT_NV61,
109 	DRM_FORMAT_NV16,
110 	DRM_FORMAT_NV21,
111 	DRM_FORMAT_NV12,
112 };
113 
sunxi_de_get_de(int nr)114 static struct sunxi_de *sunxi_de_get_de(int nr)
115 {
116 	return &de_drv->hwde[nr];
117 }
118 
119 /*get crtc count*/
sunxi_de_get_count(void)120 int sunxi_de_get_count(void)
121 {
122 	/* return the DE count */
123 	return de_drv->de_cnt;
124 }
125 
sunxi_de_get_funcs(int nr)126 struct sunxi_de_funcs *sunxi_de_get_funcs(int nr)
127 {
128 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
129 
130 	return (struct sunxi_de_funcs *)hwde->funcs;
131 }
132 
sunxi_de_clk_enable(void)133 static int sunxi_de_clk_enable(void)
134 {
135 	int ret;
136 
137 	ret = clk_prepare_enable(de_drv->mclk);
138 	if (ret < 0) {
139 		DRM_ERROR("Enable de clk failed\n");
140 		return ret;
141 	}
142 
143 	ret = clk_prepare_enable(de_drv->mclk_bus);
144 	if (ret < 0) {
145 		DRM_ERROR("Enable de bus clk failed\n");
146 		return ret;
147 	}
148 
149 	return 0;
150 }
151 
sunxi_de_clk_disable(void)152 static void sunxi_de_clk_disable(void)
153 {
154 	clk_disable_unprepare(de_drv->mclk);
155 }
156 
disp_feat_is_using_rcq(unsigned int disp)157 int disp_feat_is_using_rcq(unsigned int disp)
158 {
159 #if defined(DE_VERSION_V33X)
160        return de_feat_is_using_rcq(disp);
161 #endif
162        return 0;
163 }
164 
disp_feat_is_using_wb_rcq(unsigned int wb)165 int disp_feat_is_using_wb_rcq(unsigned int wb)
166 {
167 #if defined(DE_VERSION_V33X)
168        return de_feat_is_using_wb_rcq(wb);
169 #endif
170        return 0;
171 }
172 
sunxi_de_get_freq(int nr)173 static unsigned long sunxi_de_get_freq(int nr)
174 {
175 	return clk_get_rate(de_drv->mclk);
176 }
177 
sunxi_de_get_layer_count(int nr)178 static int sunxi_de_get_layer_count(int nr)
179 {
180 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
181 
182 	return ((hwde->vichannel_cnt * hwde->layers_per_vichannel)
183 		+ (hwde->uichannel_cnt * hwde->layers_per_uichannel));
184 }
185 
sunxi_de_get_vi_layer_count(int nr)186 static int sunxi_de_get_vi_layer_count(int nr)
187 {
188 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
189 
190 	return (hwde->vichannel_cnt * hwde->layers_per_vichannel);
191 }
192 
sunxi_de_get_ui_layer_count(int nr)193 static int sunxi_de_get_ui_layer_count(int nr)
194 {
195 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
196 
197 	return (hwde->uichannel_cnt * hwde->layers_per_uichannel);
198 }
199 
sunxi_de_layer_is_video(int nr,int layer_id)200 static int sunxi_de_layer_is_video(int nr, int layer_id)
201 {
202 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
203 
204 	if (layer_id >= sunxi_de_get_layer_count(nr)) {
205 		DRM_ERROR("layer:%d if is out of range\n", layer_id);
206 		return -1;
207 	}
208 
209 	if (layer_id < (hwde->vichannel_cnt * hwde->layers_per_vichannel))
210 		return 1;
211 	return 0;
212 }
213 
sunxi_de_get_layer_channel_id(int nr,int layer_id)214 static int sunxi_de_get_layer_channel_id(int nr, int layer_id)
215 {
216 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
217 
218 	if (sunxi_de_layer_is_video(nr, layer_id))
219 		return layer_id / hwde->layers_per_vichannel;
220 
221 	return hwde->vichannel_cnt +
222 		((layer_id - sunxi_de_get_vi_layer_count(nr)) / hwde->layers_per_uichannel);
223 }
224 
sunxi_de_get_layer_id_within_chanel(int nr,int top_layer_id)225 static int sunxi_de_get_layer_id_within_chanel(int nr, int top_layer_id)
226 {
227 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
228 
229 	if (top_layer_id < sunxi_de_get_vi_layer_count(nr))
230 		return top_layer_id % hwde->layers_per_vichannel;
231 
232 	return top_layer_id % hwde->layers_per_uichannel;
233 }
234 
sunxi_de_get_layer_formats(int nr,unsigned int layer_id,const unsigned int ** formats,unsigned int * count)235 static int sunxi_de_get_layer_formats(int nr, unsigned int layer_id,
236 				const unsigned int **formats,
237 				unsigned int *count)
238 {
239 	int is_video;
240 
241 	is_video = sunxi_de_layer_is_video(nr, layer_id);
242 	if (is_video < 0) {
243 		DRM_ERROR("judge layer_is_video failed\n");
244 		return -1;
245 	}
246 
247 	if (is_video) {
248 		*formats = vi_layer_formats;
249 		*count = ARRAY_SIZE(vi_layer_formats);
250 	} else {
251 		*formats = ui_layer_formats;
252 		*count = ARRAY_SIZE(ui_layer_formats);
253 	}
254 
255 	return 0;
256 }
257 
sunxi_de_is_support_tcon(int nr,int tcon_id)258 static bool sunxi_de_is_support_tcon(int nr, int tcon_id)
259 {
260 	return true;
261 }
262 
sunxi_de_get_attached_tcon_id(int nr)263 static int sunxi_de_get_attached_tcon_id(int nr)
264 {
265 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
266 
267 	if (!hwde->enable) {
268 		DRM_ERROR("DE%d is NOT be set to enable\n", hwde->id);
269 		return -1;
270 	}
271 
272 	return hwde->info.hwdev_index;
273 }
274 
sunxi_de_is_enable(int nr)275 static bool sunxi_de_is_enable(int nr)
276 {
277 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
278 
279 	return hwde->enable;
280 }
281 
282 #if defined(CONFIG_AW_DRM_DE_V33X)
sunxi_de_layer_enhance_apply(unsigned int disp,struct disp_layer_config_data * data,unsigned int layer_num)283 static int sunxi_de_layer_enhance_apply(unsigned int disp,
284 	struct disp_layer_config_data *data,
285 	unsigned int layer_num)
286 {
287 	struct disp_enhance_chn_info *ehs_info;
288 	struct de_rtmx_context *ctx = de_rtmx_get_context(disp);
289 	struct de_chn_info *chn_info = ctx->chn_info;
290 	u32 vi_chn_num = de_feat_get_num_vi_chns(disp);
291 	u32 i;
292 
293 	ehs_info = kmalloc(sizeof(struct disp_enhance_chn_info) * vi_chn_num,
294 			GFP_KERNEL | __GFP_ZERO);
295 	if (ehs_info == NULL) {
296 		pr_warn("%s failed to kmalloc!\n", __func__);
297 		return -1;
298 	}
299 	memset((void *)ehs_info, 0, sizeof(struct disp_enhance_chn_info)
300 			* vi_chn_num);
301 	for (i = 0; i < layer_num; ++i, ++data) {
302 		if (data->config.enable
303 			&& (data->config.channel < vi_chn_num)) {
304 			struct disp_enhance_layer_info *ehs_layer_info =
305 					&ehs_info[data->config.channel]
306 					.layer_info[data->config.layer_id];
307 
308 			ehs_layer_info->fb_size.width =
309 				data->config.info.fb.size[0].width;
310 			ehs_layer_info->fb_size.height =
311 				data->config.info.fb.size[0].height;
312 			ehs_layer_info->fb_crop.x =
313 				data->config.info.fb.crop.x >> 32;
314 			ehs_layer_info->fb_crop.y =
315 				data->config.info.fb.crop.y >> 32;
316 			ehs_layer_info->en = 1;
317 			ehs_layer_info->format = data->config.info.fb.format;
318 		}
319 	}
320 	for (i = 0; i < vi_chn_num; i++) {
321 		ehs_info[i].ovl_size.width = chn_info->ovl_out_win.width;
322 		ehs_info[i].ovl_size.height = chn_info->ovl_out_win.height;
323 		ehs_info[i].bld_size.width = chn_info->scn_win.width;
324 		ehs_info[i].bld_size.height = chn_info->scn_win.height;
325 
326 	}
327 	/* set enhance size */
328 	de_enhance_layer_apply(disp, ehs_info);
329 	kfree(ehs_info);
330 	return 0;
331 }
332 
333 #endif
334 
sunxi_de_single_layer_apply(int nr,struct disp_layer_config_data * data)335 static int sunxi_de_single_layer_apply(
336 	int nr, struct disp_layer_config_data *data)
337 {
338 	int ret = 0, layer_id;
339 	struct disp_csc_config csc_cfg;
340 	struct disp_layer_config_data *data_tmp = NULL;
341 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
342 
343 	csc_cfg.out_fmt =
344 		(hwde->info.cs == DISP_CSC_TYPE_RGB) ? DE_RGB : DE_YUV;
345 	if ((data->config.info.screen_win.height < 1280)
346 	    && (data->config.info.screen_win.height < 720))
347 		csc_cfg.out_mode = DE_BT601;
348 	else
349 		csc_cfg.out_mode = DE_BT709;
350 	csc_cfg.out_color_range = hwde->info.color_range;
351 
352 #if defined(CONFIG_AW_DRM_DE_V33X)
353 #elif defined(CONFIG_AW_DRM_DE_V2X)
354 	de_al_mgr_apply_color(nr, &csc_cfg);
355 #elif defined(CONFIG_AW_DRM_DE_SUN50IW1)
356 #else
357 	"de_al_mgr_apply_color has NOT been implemented!"
358 #endif
359 
360 	layer_id = data->config.channel * 4 + data->config.layer_id;
361 	data_tmp = &hwde->layer_config_data[layer_id];
362 	memcpy(data_tmp, data,
363 		sizeof(struct disp_layer_config_data));
364 
365 #ifdef CONFIG_AW_DRM_DE_V33X
366 	de_rtmx_layer_apply(nr, hwde->layer_config_data,
367 		sunxi_de_get_layer_count(nr));
368 	sunxi_de_layer_enhance_apply(nr, hwde->layer_config_data,
369 		sunxi_de_get_layer_count(nr));
370 #else
371 	ret = de_al_lyr_apply(nr, hwde->layer_config_data,
372 		sunxi_de_get_layer_count(nr), false);
373 	if (ret) {
374 		DRM_ERROR("de_al_lyr_apply failed\n");
375 		return ret;
376 	}
377 #endif
378 
379 	//de_al_mgr_update_regs(nr);
380 
381 	hwde->layer_enabled[data->config.channel][data->config.layer_id]
382 		= data->config.enable;
383 
384 	return 0;
385 }
386 
sunxi_de_multi_layers_apply(int nr,struct disp_layer_config_data * data,unsigned int layer_num)387 int sunxi_de_multi_layers_apply(int nr, struct disp_layer_config_data *data,
388 					unsigned int layer_num)
389 {
390 	int i, layer_id, ret;
391 	struct disp_csc_config csc_cfg;
392 	struct disp_layer_config_data *data_tmp = NULL;
393 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
394 
395 	csc_cfg.out_fmt =
396 		(hwde->info.cs == DISP_CSC_TYPE_RGB) ? DE_RGB : DE_YUV;
397 	if ((data->config.info.screen_win.height < 1280)
398 	    && (data->config.info.screen_win.height < 720))
399 		csc_cfg.out_mode = DE_BT601;
400 	else
401 		csc_cfg.out_mode = DE_BT709;
402 	csc_cfg.out_color_range = hwde->info.color_range;
403 #if defined(CONFIG_AW_DRM_DE_V33X)
404 
405 #elif defined(CONFIG_AW_DRM_DE_V2X)
406 	de_al_mgr_apply_color(nr, &csc_cfg);
407 #elif defined(CONFIG_AW_DRM_DE_SUN50IW1)
408 #else
409 	"de_al_mgr_apply_color has NOT been implemented!"
410 #endif
411 
412 	for (i = 0; i < layer_num; i++) {
413 		layer_id = data[i].config.channel * 4 + data[i].config.layer_id;
414 		data_tmp = &hwde->layer_config_data[layer_id];
415 		memcpy(data_tmp, &data[i],
416 			sizeof(struct disp_layer_config_data));
417 		hwde->layer_enabled[data[i].config.channel][data[i].config.layer_id]
418 			= data[i].config.enable;
419 	}
420 
421 #ifdef CONFIG_AW_DRM_DE_V33X
422 	de_rtmx_layer_apply(nr, hwde->layer_config_data,
423 		sunxi_de_get_layer_count(nr));
424 	sunxi_de_layer_enhance_apply(nr, hwde->layer_config_data,
425 		sunxi_de_get_layer_count(nr));
426 #else
427 	ret = de_al_lyr_apply(nr, hwde->layer_config_data,
428 			sunxi_de_get_layer_count(nr), false);
429 	if (ret) {
430 		DRM_ERROR("de_al_lyr_apply failed\n");
431 		return ret;
432 	}
433 #endif
434 
435 	return 0;
436 }
437 
438 /*enhance*/
sunxi_de_enhance_apply(int nr,struct disp_enhance_config * config)439 static int sunxi_de_enhance_apply(int nr,
440 		struct disp_enhance_config *config)
441 {
442 #ifndef CONFIG_AW_DRM_DE_V33X
443 	struct disp_csc_config csc_config;
444 
445 	if (config->flags & ENH_MODE_DIRTY) {
446 		de_dcsc_get_config(nr, &csc_config);
447 		csc_config.enhance_mode = (config->info.mode >> 16) & 0xffff;
448 		de_dcsc_apply(nr, &csc_config);
449 	}
450 #endif
451 
452 	return de_enhance_apply(nr, config);
453 }
454 
sunxi_de_enhance_sync(int nr)455 static void sunxi_de_enhance_sync(int nr)
456 {
457 	//struct sunxi_de *hwde = sunxi_de_get_de(nr);
458 
459 	de_enhance_update_regs(nr);
460 	de_enhance_sync(nr);
461 	de_enhance_tasklet(nr);
462 }
463 
sunxi_de_smbl_sync(int nr)464 static void sunxi_de_smbl_sync(int nr)
465 {
466 	de_smbl_update_regs(nr);
467 	de_smbl_tasklet(nr);
468 }
469 
470 
sunxi_de_enable(int nr,struct disp_manager_data * data)471 static int sunxi_de_enable(int nr, struct disp_manager_data *data)
472 {
473 	int ret = 0;
474 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
475 
476 	if (hwde->enable) {
477 		DRM_INFO("[SUNXI-DE]WARN:sunxi has been enable,"
478 			"do NOT enable it again\n");
479 		return 0;
480 	}
481 
482 	hwde->enable = true;
483 	memcpy(&hwde->info, &data->config,
484 		sizeof(struct disp_manager_info));
485 #ifdef CONFIG_AW_DRM_DE_V33X
486 	de_rtmx_start(nr);
487 	de_rtmx_mgr_apply(nr, data);
488 	de_rtmx_update_reg_ahb(nr);
489 #else
490 
491 	sunxi_de_clk_enable();
492 	de_clk_enable(DE_CLK_CORE0 + nr);
493 
494 #ifndef CONFIG_AW_DRM_DE_SUN50IW1
495 	de_update_clk_rate(data->config.de_freq);
496 #endif
497 	de_update_device_fps(nr, data->config.device_fps);
498 
499 	ret = de_al_mgr_apply(nr, data);
500 	if (ret) {
501 		DRM_ERROR("de_al_mgr_apply failed\n");
502 		return ret;
503 	}
504 
505 	de_al_mgr_update_regs(nr);
506 
507 #if IS_ENABLED(CONFIG_AW_IOMMU)
508 		sunxi_enable_device_iommu(DE_MASTOR_ID, true);
509 #endif
510 	/*de_rtmx_set_dbuff_rdy(nr);*/
511 #endif
512 
513 /*enhance*/
514 	ret = sunxi_de_enhance_apply(nr,
515 		&hwde->enhance_config);
516 	if (ret) {
517 		DRM_ERROR("sunxi_de_enhance_apply failed\n");
518 		return ret;
519 	}
520 
521 /*smbl*/
522 	ret = de_smbl_apply(nr, &hwde->smbl_info);
523 	if (ret) {
524 		DRM_ERROR("de_smbl_apply failed\n");
525 		return ret;
526 	}
527 
528 	return 0;
529 }
530 
531 /*int sunxi_de_sw_enable(int nr)
532 {
533 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
534 
535 	hwde->is_assigned = true;
536 	sunxi_de_clk_enable();
537 	return 0;
538 }*/
539 
sunxi_de_disable(int nr,struct disp_manager_data * data)540 static void sunxi_de_disable(int nr, struct disp_manager_data *data)
541 {
542 	int ret = 0;
543 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
544 
545 	if (!hwde->enable) {
546 		DRM_INFO("[SUNXI-DE]WARN:sunxi has NOT been enable,"
547 			"can NOT enable it\n");
548 		return;
549 	}
550 
551 	hwde->enable = false;
552 	memcpy(&hwde->info, &data->config,
553 		sizeof(struct disp_manager_info));
554 #ifdef CONFIG_AW_DRM_DE_V33X
555 	de_rtmx_stop(nr);
556 #else
557 	ret = de_al_mgr_apply(nr, data);
558 	if (ret) {
559 		DRM_ERROR("de_al_mgr_apply failed\n");
560 		return;
561 	}
562 
563 	de_al_mgr_update_regs(nr);
564 	de_rtmx_set_dbuff_rdy(nr);
565 #if !defined(CONFIG_AW_DRM_DE_V33X)
566 	de_clk_disable(DE_CLK_CORE0 + nr);
567 #endif
568 
569 	sunxi_de_clk_disable();
570 #endif
571 	return;
572 }
573 
574 
sunxi_de_is_use_irq(int nr)575 static bool sunxi_de_is_use_irq(int nr)
576 {
577 	return false;
578 }
579 
sunxi_de_get_irq_no(int nr)580 static unsigned int sunxi_de_get_irq_no(int nr)
581 {
582 	return 0;
583 }
584 
sunxi_de_query_irq(int nr)585 static int sunxi_de_query_irq(int nr)
586 {
587 	int tcon_id, irq_query;
588 
589 	tcon_id = sunxi_de_get_attached_tcon_id(nr);
590 	if (tcon_id < 0) {
591 		DRM_ERROR("DE%d has No atteched tcon\n", nr);
592 		return -1;
593 	}
594 
595 	irq_query = sunxi_tcon_query_irq(tcon_id);
596 	if (!irq_query) {
597 		DRM_ERROR("irq_query result: No IRQ\n");
598 		return -1;
599 	}
600 
601 	return 0;
602 }
603 
604 
605 /*
606  * The main task during de vsync is to update de registers and make it effective
607  */
sunxi_de_event_proc(int nr,bool update)608 static int sunxi_de_event_proc(int nr, bool update)
609 {
610 	int tcon_id;
611 	//struct sunxi_de *hwde = sunxi_de_get_de(nr);
612 
613 	if (!update)
614 		return 0;
615 
616 #if defined(CONFIG_AW_DRM_DE_V33X)
617 	de_rtmx_update_reg_ahb(nr);
618 #else
619 	tcon_id = sunxi_de_get_attached_tcon_id(nr);
620 	if (tcon_id < 0) {
621 		DRM_ERROR("DE%d has No atteched tcon\n", nr);
622 		return -1;
623 	}
624 
625 	if (!sunxi_tcon_sync_time_is_enough(tcon_id)) {
626 		de_al_mgr_update_regs(nr);
627 		DRM_INFO("WARNING: NO enough time left to sync reg\n");
628 		return -1;
629 	}
630 
631 	de_rtmx_set_dbuff_rdy(nr);
632 	de_al_mgr_update_regs(nr);
633 #endif
634 
635 	/*enhance*/
636 	sunxi_de_enhance_sync(nr);
637 
638 	/*smbl*/
639 	sunxi_de_smbl_sync(nr);
640 
641 	return 0;
642 }
643 
sunxi_updata_crtc_freq(unsigned long rate)644 void sunxi_updata_crtc_freq(unsigned long rate)
645 {
646 #ifdef CONFIG_AW_DRM_DE_V2X
647 	de_update_clk_rate(rate);
648 #endif
649 #ifdef CONFIG_AW_DRM_DE_SUN50IW1
650 	de_update_de_frequency(rate);
651 #endif
652 }
653 
654 /*enhance*/
sunxi_de_set_enhance(int nr,int mode,bool enable,int width,int height,int conn_type)655 static int sunxi_de_set_enhance(int nr,
656 	int mode, bool enable, int width, int height, int conn_type)
657 {
658 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
659 	struct disp_enhance_config *config = &hwde->enhance_config;
660 
661 	if (!enable) {
662 		config->info.enable = 0;
663 		config->flags |= ENH_ENABLE_DIRTY;
664 		goto out;
665 	}
666 
667 	config->info.mode =
668 		(config->info.mode & 0xffff) | (mode << 16);
669 	config->flags |= ENH_MODE_DIRTY;
670 
671 	if (!width || !height) {
672 		DRM_ERROR("invalid crtc size, width:%d height:%d\n",
673 					width, height);
674 		return -1;
675 	}
676 
677 	config->info.size.width = width;
678 	config->info.size.height = height;
679 	config->flags |= ENH_SIZE_DIRTY;
680 
681 	if (conn_type == DISP_OUTPUT_TYPE_HDMI)
682 		config->info.mode = (config->info.mode & 0xffff0000) | 1;
683 	else
684 		config->info.mode = (config->info.mode & 0xffff0000) | 0;
685 
686 	config->info.enable = 1;
687 	config->flags |= ENH_ENABLE_DIRTY;
688 
689 out:
690 	return sunxi_de_enhance_apply(nr, config);
691 
692 }
693 
sunxi_de_get_enhance(int nr,int * mode,bool * enable,int * width,int * height)694 static void sunxi_de_get_enhance(int nr,
695 	int *mode, bool *enable, int *width, int *height)
696 {
697 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
698 	struct disp_enhance_config *config = &hwde->enhance_config;
699 
700 	if (mode)
701 		*mode = config->info.mode;
702 	if (enable)
703 		*enable = config->info.enable;
704 	if (width)
705 		*width = config->info.size.width;
706 	if (height)
707 		*height = config->info.size.height;
708 }
709 
710 /*smbl*/
sunxi_de_is_support_smbl(int nr)711 static bool sunxi_de_is_support_smbl(int nr)
712 {
713 	bool ret;
714 
715 	ret = de_feat_is_support_smbl(nr) ? true : false;
716 
717 	return ret;
718 }
719 
sunxi_de_set_smbl(int nr,bool enable,struct disp_rect * rect)720 static int sunxi_de_set_smbl(int nr, bool enable,
721 			struct disp_rect *rect)
722 {
723 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
724 	struct disp_smbl_info *info = &hwde->smbl_info;
725 
726 	memcpy(&info->window, rect, sizeof(struct disp_rect));
727 	info->flags |= SMBL_DIRTY_WINDOW;
728 
729 	info->enable = enable;
730 	info->flags |= SMBL_DIRTY_ENABLE;
731 
732 	return de_smbl_apply(nr, info);
733 }
734 
sunxi_de_get_smbl(int nr,bool * enable,struct disp_rect * rect)735 static void sunxi_de_get_smbl(int nr, bool *enable,
736 			struct disp_rect *rect)
737 {
738 	struct sunxi_de *hwde = sunxi_de_get_de(nr);
739 	struct disp_smbl_info *info = &hwde->smbl_info;
740 
741 	if (rect)
742 		memcpy(rect, &info->window, sizeof(struct disp_rect));
743 
744 	if (enable)
745 		*enable = info->enable;
746 }
747 
748 static const struct sunxi_de_funcs de_funcs = {
749 	.is_support_tcon = sunxi_de_is_support_tcon,
750 	.get_freq = sunxi_de_get_freq,
751 
752 	.get_layer_count = sunxi_de_get_layer_count,
753 	.get_vi_layer_count = sunxi_de_get_vi_layer_count,
754 	.get_ui_layer_count = sunxi_de_get_ui_layer_count,
755 	.get_layer_channel_id = sunxi_de_get_layer_channel_id,
756 	.get_layer_id_within_chanel = sunxi_de_get_layer_id_within_chanel,
757 	.get_layer_formats = sunxi_de_get_layer_formats,
758 	.single_layer_apply = sunxi_de_single_layer_apply,
759 	.multi_layers_apply = sunxi_de_multi_layers_apply,
760 
761 	.is_enable = sunxi_de_is_enable,
762 	.enable = sunxi_de_enable,
763 	.disable = sunxi_de_disable,
764 
765 	.is_use_irq =  sunxi_de_is_use_irq,
766 	.get_irq_no = sunxi_de_get_irq_no,
767 	.query_irq = sunxi_de_query_irq,
768 	.event_proc = sunxi_de_event_proc,
769 
770 	/*enhance*/
771 	.set_enhance = sunxi_de_set_enhance,
772 	.get_enhance = sunxi_de_get_enhance,
773 
774 	/*smbl*/
775 	.is_support_smbl = sunxi_de_is_support_smbl,
776 	.set_smbl = sunxi_de_set_smbl,
777 	.get_smbl = sunxi_de_get_smbl,
778 };
779 
sunxi_de_reg_dump(char * buf,unsigned int start,unsigned int end)780 static ssize_t sunxi_de_reg_dump(char *buf, unsigned int start,
781 						unsigned int end)
782 {
783 	ssize_t n = 0;
784 	unsigned int *reg, i;
785 
786 	for (i = start; i <= end; i += 4) {
787 		/*print address info*/
788 		if (i == start)
789 			n += sprintf(buf + n, "0x%06x:", i);
790 		if ((i % 16 == 0) && (i != start)) {
791 			n += sprintf(buf + n, "%s", "\n");
792 			n += sprintf(buf + n, "0x%06x:", i);
793 		}
794 
795 		/*print reg value*/
796 		reg = (unsigned int *)(de_drv->reg_base + i);
797 		n += sprintf(buf + n, "0x%08x ", *reg);
798 	}
799 
800 	n += sprintf(buf + n, "\n");
801 
802 	return n;
803 }
804 
805 
806 /**print sunxi-de info*/
de_info_show(struct device * dev,struct device_attribute * attr,char * buf)807 static ssize_t de_info_show(struct device *dev,
808 			     struct device_attribute *attr, char *buf)
809 {
810 	ssize_t i, n = 0;
811 	struct sunxi_de *hwde;
812 
813 	n += sprintf(buf + n, "%s\n", "sunxi-de info:");
814 	n += sprintf(buf + n, "virt_reg_base: 0x%lx\n", de_drv->reg_base);
815 	n += sprintf(buf + n, "de count: %u\n", de_drv->de_cnt);
816 	n += sprintf(buf + n, "clk_name:%s clk_rate: %lu  enable count:%d\n\n",
817 					__clk_get_name(de_drv->mclk),
818 					clk_get_rate(de_drv->mclk),
819 					__clk_get_enable_count(de_drv->mclk));
820 
821 	for (i = 0; i < de_drv->de_cnt; i++) {
822 		hwde = &de_drv->hwde[i];
823 		n += sprintf(buf + n, "id: %d\n", hwde->id);
824 		n += sprintf(buf + n, "vi channel count: %u\n",
825 					hwde->vichannel_cnt);
826 		n += sprintf(buf + n, "ui channel count: %u\n",
827 					hwde->uichannel_cnt);
828 		n += sprintf(buf + n, "vi layers per channel: %u\n",
829 					hwde->layers_per_vichannel);
830 		n += sprintf(buf + n, "ui layers per channel: %u\n",
831 					hwde->layers_per_uichannel);
832 		if (!hwde->irq_used) {
833 			n += sprintf(buf + n, "%s\n", "de irq is NOT used");
834 		} else {
835 			n += sprintf(buf + n, "%s\n", "de irq is used");
836 			n += sprintf(buf + n, "irq no: %u\n", hwde->irq_no);
837 			n += sprintf(buf + n, "irq enable: %d\n",
838 							hwde->irq_enable);
839 		}
840 
841 		if (hwde->enable)
842 			n += sprintf(buf + n, "%s\n", "Has been enable");
843 		else
844 			n += sprintf(buf + n, "%s\n", "Has NOT been enable");
845 		n += sprintf(buf + n, "%s", "\n");
846 	}
847 
848 	return n;
849 }
850 
de_info_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)851 static ssize_t de_info_store(struct device *dev,
852 			      struct device_attribute *attr,
853 			      const char *buf, size_t count)
854 {
855 	return count;
856 }
857 
858 static DEVICE_ATTR(info, 0660, de_info_show, de_info_store);
859 
de_top_reg_show(struct device * dev,struct device_attribute * attr,char * buf)860 static ssize_t de_top_reg_show(struct device *dev,
861 			     struct device_attribute *attr, char *buf)
862 {
863 	ssize_t n = 0;
864 
865 	if (!__clk_is_enabled(de_drv->mclk)) {
866 		n += sprintf(buf + n, "%s\n",
867 			"ERROR:de clk is NOT enabled, can NOT dump reg");
868 		return n;
869 	}
870 
871 	n += sprintf(buf + n, "TOP DE reg:\n");
872 	n += sunxi_de_reg_dump(n + buf, 0, 0x1c);
873 	return n;
874 }
875 
de_top_reg_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)876 static ssize_t de_top_reg_store(struct device *dev,
877 			      struct device_attribute *attr,
878 			      const char *buf, size_t count)
879 {
880 	return count;
881 }
882 
883 static DEVICE_ATTR(top_reg, 0660, de_top_reg_show, de_top_reg_store);
884 
de_rtmx_reg_show(struct device * dev,struct device_attribute * attr,char * buf)885 static ssize_t de_rtmx_reg_show(struct device *dev,
886 			     struct device_attribute *attr, char *buf)
887 {
888 	ssize_t n = 0;
889 	int i, j;
890 	bool vi_en = 0, ui_en = 0;
891 	unsigned int start_addr, end_addr;
892 	struct sunxi_de *hwde = &de_drv->hwde[0];
893 
894 	n += sprintf(buf + n, "RT-Mix0-glb reg:\n");
895 	n += sunxi_de_reg_dump(n + buf, 0x100000, 0x10000c);
896 
897 	n += sprintf(buf + n, "RT-Mix0-bld reg:\n");
898 	start_addr = 0x101000;
899 	end_addr = start_addr + 0xfc;
900 	n += sunxi_de_reg_dump(n + buf, start_addr, end_addr);
901 
902 	n += sprintf(buf + n, "vichannel status:\n");
903 	for (i = 0; i < hwde->vichannel_cnt; i++) {
904 		vi_en = 0;
905 		for (j = 0; j < hwde->layers_per_vichannel; j++) {
906 			if (!hwde->layer_enabled[i][j]) {
907 				n += sprintf(buf + n, "CH%d-LAYER%d NOT enabled\n", i, j);
908 				continue;
909 			}
910 			n += sprintf(buf + n, "CH%d-LAYER%d IS enabled\n", i, j);
911 
912 			n += sprintf(buf + n, "CH%d-LAYER%d reg:\n", i, j);
913 			n += sprintf(buf + n, "VI General control reg:\n");
914 			start_addr = 0x102000 + (i * 0x1000) + j * 0x30;
915 			end_addr = start_addr + 0x2c;
916 			n += sunxi_de_reg_dump(n + buf, start_addr, end_addr);
917 			n += sprintf(buf + n, "%s", "\n");
918 
919 			n += sprintf(buf + n, "VI fill color reg:\n");
920 			start_addr = 0x102000 + (i * 0x1000) + j * 0x4;
921 			end_addr = start_addr + 0;
922 			n += sunxi_de_reg_dump(n + buf, start_addr, end_addr);
923 			n += sprintf(buf + n, "%s", "\n");
924 			vi_en = 1;
925 		}
926 
927 		/*No layer in this channel is enabled*/
928 		if (!vi_en)
929 			continue;
930 
931 		n += sprintf(buf + n, "VI TOP reg:\n");
932 		start_addr = 0x102000 + (i * 0x1000) + 0xd0;
933 		end_addr = 0x102000 + (i * 0x1000) + 0xfc;
934 		n += sunxi_de_reg_dump(n + buf, start_addr, end_addr);
935 		n += sprintf(buf + n, "%s", "\n\n");
936 	}
937 
938 	n += sprintf(buf + n, "uichannel status:\n");
939 	for (i = 0; i < hwde->uichannel_cnt; i++) {
940 		ui_en = 0;
941 		for (j = 0; j < hwde->layers_per_uichannel; j++) {
942 			if (!hwde->layer_enabled[i + hwde->vichannel_cnt][j]) {
943 				n += sprintf(buf + n, "CH%d-LAYER%d NOT enabled\n",
944 						i + hwde->vichannel_cnt, j);
945 				continue;
946 			}
947 			n += sprintf(buf + n, "CH%d-LAYER%d reg:\n",
948 					i + hwde->vichannel_cnt, j);
949 			n += sprintf(buf + n, "UI General control reg:\n");
950 			start_addr = 0x102000 + (0x1000 * hwde->vichannel_cnt)
951 						+ (i * 0x1000) + j * 0x20;
952 			end_addr = start_addr + 0x18;
953 			n += sunxi_de_reg_dump(n + buf, start_addr, end_addr);
954 			n += sprintf(buf + n, "%s", "\n");
955 			ui_en = 1;
956 		}
957 
958 		/*No layer in this channel is enabled*/
959 		if (!ui_en)
960 			continue;
961 
962 		n += sprintf(buf + n, "CH%d UI TOP reg:\n", i + hwde->vichannel_cnt);
963 		start_addr = 0x102000 + (0x1000 * hwde->vichannel_cnt)
964 						+ (i * 0x1000) + 0x80;
965 		end_addr = 0x102000 + (0x1000 * hwde->vichannel_cnt)
966 						+ (i * 0x1000) + 0x88;
967 		n += sunxi_de_reg_dump(n + buf, start_addr, end_addr);
968 		n += sprintf(buf + n, "%s", "\n\n");
969 	}
970 
971 	n += sprintf(buf + n, "%s", "\n");
972 	return n;
973 }
974 
de_rtmx_reg_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)975 static ssize_t de_rtmx_reg_store(struct device *dev,
976 			      struct device_attribute *attr,
977 			      const char *buf, size_t count)
978 {
979 	return count;
980 }
981 
982 static DEVICE_ATTR(rtmx_reg, 0660, de_rtmx_reg_show, de_rtmx_reg_store);
983 
984 
de_vsu_reg_show(struct device * dev,struct device_attribute * attr,char * buf)985 static ssize_t de_vsu_reg_show(struct device *dev,
986 			     struct device_attribute *attr, char *buf)
987 {
988 	ssize_t n = 0;
989 	int i, j, vi_chn_cnt;
990 	unsigned int start_addr, end_addr;
991 	struct sunxi_de *hwde = &de_drv->hwde[0];
992 
993 	if (!__clk_is_enabled(de_drv->mclk)) {
994 		n += sprintf(buf + n, "%s\n",
995 			"ERROR:de clk is NOT enabled, can NOT dump reg");
996 		return n;
997 	}
998 
999 	vi_chn_cnt = hwde->vichannel_cnt;
1000 	for (i = 0; i < vi_chn_cnt; i++) {
1001 		for (j = 0; j < hwde->layers_per_vichannel; j++) {
1002 			if (hwde->layer_enabled[i][j])
1003 				break;
1004 		}
1005 
1006 		if (j >= hwde->layers_per_vichannel) {
1007 			n += sprintf(buf + n, "Video CH%d is NOT enabled\n", i);
1008 			continue;
1009 		}
1010 
1011 		n += sprintf(buf + n, "CH%d VSU reg:\n", i);
1012 		start_addr = 0x00100000 + ((i + 1) * 0x20000);
1013 		end_addr = start_addr + 0xdc;
1014 		n += sunxi_de_reg_dump(n + buf, start_addr, end_addr);
1015 	}
1016 
1017 	return n;
1018 }
1019 
de_vsu_reg_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)1020 static ssize_t de_vsu_reg_store(struct device *dev,
1021 			      struct device_attribute *attr,
1022 			      const char *buf, size_t count)
1023 {
1024 	return count;
1025 }
1026 
1027 static DEVICE_ATTR(vsu_reg, 0660, de_vsu_reg_show, de_vsu_reg_store);
1028 
de_gsu_reg_show(struct device * dev,struct device_attribute * attr,char * buf)1029 static ssize_t de_gsu_reg_show(struct device *dev,
1030 			     struct device_attribute *attr, char *buf)
1031 {
1032 	ssize_t n = 0;
1033 	int i, j, vi_chn_cnt, ui_chn_cnt;
1034 	unsigned int start_addr, end_addr;
1035 	struct sunxi_de *hwde = &de_drv->hwde[0];
1036 
1037 	if (!__clk_is_enabled(de_drv->mclk)) {
1038 		n += sprintf(buf + n, "%s\n",
1039 			"ERROR:de clk is NOT enabled, can NOT dump reg");
1040 		return n;
1041 	}
1042 
1043 	vi_chn_cnt = hwde->vichannel_cnt;
1044 	ui_chn_cnt = hwde->uichannel_cnt;
1045 	for (i = 0; i < ui_chn_cnt; i++) {
1046 		for (j = 0; j < hwde->layers_per_uichannel; j++) {
1047 			if (hwde->layer_enabled[i + vi_chn_cnt][j])
1048 				break;
1049 		}
1050 
1051 		if (j >= hwde->layers_per_uichannel) {
1052 			n += sprintf(buf + n, "UI CHANNEL, CH%d is NOT enabled\n",
1053 					i + vi_chn_cnt);
1054 			continue;
1055 		}
1056 
1057 		n += sprintf(buf + n, "CH%d GSU reg:\n", i + vi_chn_cnt);
1058 		start_addr = 0x00100000 + (vi_chn_cnt * 0x20000) + (i * 0x10000);
1059 		end_addr = start_addr + 0x9c;
1060 		n += sunxi_de_reg_dump(n + buf, start_addr, end_addr);
1061 	}
1062 
1063 	return n;
1064 }
1065 
de_gsu_reg_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)1066 static ssize_t de_gsu_reg_store(struct device *dev,
1067 			      struct device_attribute *attr,
1068 			      const char *buf, size_t count)
1069 {
1070 	return count;
1071 }
1072 
1073 static DEVICE_ATTR(gsu_reg, 0660, de_gsu_reg_show, de_gsu_reg_store);
1074 
1075 
1076 /*enhance is belongs to POST-PROCESS1,
1077  * Only use in video chanel
1078  */
de_enhance_reg_show(struct device * dev,struct device_attribute * attr,char * buf)1079 static ssize_t de_enhance_reg_show(struct device *dev,
1080 			     struct device_attribute *attr, char *buf)
1081 {
1082 	ssize_t n = 0;
1083 	unsigned int start_addr, end_addr;
1084 
1085 	if (!__clk_is_enabled(de_drv->mclk)) {
1086 		n += sprintf(buf + n, "%s\n",
1087 			"ERROR:de clk is NOT enabled, can NOT dump reg");
1088 		return n;
1089 	}
1090 
1091 	n += sprintf(buf + n, "FCE reg:\n");
1092 	start_addr = 0x00100000 + 0xa0000;
1093 	end_addr = start_addr + 0x40;
1094 	n += sunxi_de_reg_dump(n + buf, start_addr, end_addr);
1095 
1096 	n += sprintf(buf + n, "LTI reg:\n");
1097 	start_addr = 0x00100000 + 0xa4000;
1098 	end_addr = start_addr + 0xcc;
1099 	n += sunxi_de_reg_dump(n + buf, start_addr, end_addr);
1100 
1101 	n += sprintf(buf + n, "PEAK reg:\n");
1102 	start_addr = 0x00100000 + 0xa6000;
1103 	end_addr = start_addr + 0xcc;
1104 	n += sunxi_de_reg_dump(n + buf, start_addr, end_addr);
1105 
1106 	n += sprintf(buf + n, "ASE reg:\n");
1107 	start_addr = 0x00100000 + 0xa8000;
1108 	end_addr = start_addr + 0x10;
1109 	n += sunxi_de_reg_dump(n + buf, start_addr, end_addr);
1110 
1111 	n += sprintf(buf + n, "FCC reg:\n");
1112 	start_addr = 0x00100000 + 0xaa000;
1113 	end_addr = start_addr + 0x90;
1114 	n += sunxi_de_reg_dump(n + buf, start_addr, end_addr);
1115 
1116 	return n;
1117 }
1118 
de_enhance_reg_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)1119 static ssize_t de_enhance_reg_store(struct device *dev,
1120 			      struct device_attribute *attr,
1121 			      const char *buf, size_t count)
1122 {
1123 	return count;
1124 }
1125 
1126 static DEVICE_ATTR(enhance_reg, 0660, de_enhance_reg_show, de_enhance_reg_store);
1127 
sunxi_disp_hal_debug_show(struct device * device,struct device_attribute * attr,char * buf)1128 static ssize_t sunxi_disp_hal_debug_show(struct device *device,
1129 			   struct device_attribute *attr,
1130 			   char *buf)
1131 {
1132 	ssize_t n = 0;
1133 #if !defined(CONFIG_AW_DRM_DE_V33X)
1134 	/*n += sprintf(buf + n, "hal_debug_level=%d\n",
1135 				de_get_hal_debug_level());*/
1136 #endif
1137 	return n;
1138 }
1139 
sunxi_disp_hal_debug_store(struct device * device,struct device_attribute * attr,const char * buf,size_t count)1140 static ssize_t sunxi_disp_hal_debug_store(struct device *device,
1141 			   struct device_attribute *attr,
1142 			   const char *buf, size_t count)
1143 {
1144 	unsigned int level;
1145 
1146 	if (kstrtoul(buf, 0, (unsigned long *)&level) < 0) {
1147 		DRM_ERROR("ERROR input\n");
1148 		return 0;
1149 	}
1150 #if !defined(CONFIG_AW_DRM_DE_V33X)
1151 	/*de_set_hal_debug_level(level);*/
1152 #endif
1153 	return count;
1154 }
1155 
1156 static DEVICE_ATTR(disp_hal_debug, 0660,
1157 	sunxi_disp_hal_debug_show, sunxi_disp_hal_debug_store);
1158 
sunxi_disp_debug_show(struct device * device,struct device_attribute * attr,char * buf)1159 static ssize_t sunxi_disp_debug_show(struct device *device,
1160 			   struct device_attribute *attr,
1161 			   char *buf)
1162 {
1163 	ssize_t n = 0;
1164 
1165 	n += sprintf(buf + n, "disp_debug=%d\n",
1166 				bsp_disp_get_print_level());
1167 
1168 	return n;
1169 }
1170 
sunxi_disp_debug_store(struct device * device,struct device_attribute * attr,const char * buf,size_t count)1171 static ssize_t sunxi_disp_debug_store(struct device *device,
1172 			   struct device_attribute *attr,
1173 			   const char *buf, size_t count)
1174 {
1175 	unsigned int debug;
1176 
1177 	if (kstrtoul(buf, 0, (unsigned long *)&debug) < 0) {
1178 		DRM_ERROR("ERROR input\n");
1179 		return 0;
1180 	}
1181 
1182 	bsp_disp_set_print_level(debug);
1183 
1184 	return count;
1185 }
1186 
1187 static DEVICE_ATTR(disp_debug, 0660, sunxi_disp_debug_show, sunxi_disp_debug_store);
1188 
1189 static struct attribute *de_attributes[] = {
1190 	&dev_attr_info.attr,
1191 	&dev_attr_top_reg.attr,
1192 	&dev_attr_rtmx_reg.attr,
1193 	&dev_attr_vsu_reg.attr,
1194 	&dev_attr_gsu_reg.attr,
1195 	&dev_attr_enhance_reg.attr,
1196 	&dev_attr_disp_debug.attr,
1197 	&dev_attr_disp_hal_debug.attr,
1198 	NULL
1199 };
1200 
1201 static struct attribute_group de_attribute_group = {
1202 	.name = "attr",
1203 	.attrs = de_attributes,
1204 };
1205 
1206 
1207 #if defined(CONFIG_AW_DRM_DE_V33X)
sunxi_de_v33x_al_init(struct disp_bsp_init_para * para)1208 static int sunxi_de_v33x_al_init(struct disp_bsp_init_para *para)
1209 {
1210 	if (de_top_mem_pool_alloc())
1211 		return -1;
1212 
1213 	de_enhance_init(para);
1214 	de_smbl_init(para->reg_base[DISP_MOD_DE]);
1215 	de_rtmx_init(para);
1216 	de_wb_init(para);
1217 
1218 	return 0;
1219 }
1220 #elif defined(CONFIG_AW_DRM_DE_V33X)
sunxi_de_v3x_al_init(struct disp_bsp_init_para * para)1221 static int sunxi_de_v3x_al_init(struct disp_bsp_init_para *para)
1222 {
1223 	return 0;
1224 }
1225 #elif defined(CONFIG_AW_DRM_DE_V2X)
sunxi_de_v2x_al_init(struct disp_bsp_init_para * para)1226 static int sunxi_de_v2x_al_init(struct disp_bsp_init_para *para)
1227 {
1228 	int i;
1229 	de_al_init(para);
1230 
1231 	de_enhance_init(para);
1232 	de_ccsc_init(para);
1233 	de_dcsc_init(para);
1234 
1235 #ifndef CONFIG_EINK_PANEL_USED
1236 	wb_ebios_init(para);
1237 #endif
1238 	de_clk_set_reg_base(para->reg_base[DISP_MOD_DE]);
1239 	for (i = 0; i < DE_NUM; i++) {
1240 		if (de_feat_is_support_smbl(i))
1241 			de_smbl_init(i, para->reg_base[DISP_MOD_DE]);
1242 	}
1243 
1244 	return 0;
1245 }
1246 #elif defined(CONFIG_AW_DRM_DE_SUN50IW1)
sunxi_de_sun50iw1_al_init(struct disp_bsp_init_para * para)1247 static int sunxi_de_sun50iw1_al_init(struct disp_bsp_init_para *para)
1248 {
1249 	int i;
1250 	de_al_init(para);
1251 
1252 	de_enhance_init(para);
1253 	de_ccsc_init(para);
1254 	de_dcsc_init(para);
1255 	WB_EBIOS_Init(para);
1256 
1257 	de_clk_set_reg_base(para->reg_base[DISP_MOD_DE]);
1258 	for (i = 0; i < DE_NUM; i++) {
1259 		if (de_feat_is_support_smbl(i))
1260 			de_smbl_init(i, para->reg_base[DISP_MOD_DE]);
1261 	}
1262 
1263 	return 0;
1264 }
1265 #else
1266 	"compile error!"
1267 #endif
1268 
1269 #if defined(CONFIG_AW_DRM_DE_V33X)
1270 static int sunxi_de_v33x_al_exit(void)
1271 {
1272 	return disp_exit_al();
1273 }
1274 #elif defined(CONFIG_AW_DRM_DE_V33X)
1275 static int sunxi_de_v3x_al_exit(void)
1276 {
1277 	return 0;
1278 }
1279 #elif defined(CONFIG_AW_DRM_DE_V2X)
1280 static int sunxi_de_v2x_al_exit(void)
1281 {
1282 	de_al_exit();
1283 
1284 	de_enhance_exit();
1285 	de_ccsc_exit();
1286 	de_dcsc_exit();
1287 
1288 	wb_ebios_exit();
1289 
1290 	for (i = 0; i < DE_NUM; i++) {
1291 #if defined(SUPPORT_SMBL)
1292 		if (de_feat_is_support_smbl(i))
1293 			de_smbl_exit(i);
1294 #endif
1295 		kfree(de_drv->hwde[i].layer_config_data);
1296 	}
1297 	return 0;
1298 }
1299 #elif defined(CONFIG_AW_DRM_DE_SUN50IW1)
1300 static int sunxi_de_sun50iw1_al_exit(void)
1301 {
1302 	return 0;
1303 }
1304 #else
1305 	"compile error!"
1306 #endif
1307 
1308 
sunxi_de_init_al(void)1309 static int sunxi_de_init_al(void)
1310 {
1311 	struct disp_bsp_init_para *para;
1312 
1313 	para = sunxi_disp_get_bsp_init_para();
1314 	if (!para) {
1315 		DRM_ERROR("[sunxi-de] sunxi_disp_get_bsp_init_para failed\n");
1316 		return -1;
1317 	}
1318 
1319 	para->reg_base[DISP_MOD_DE] = de_drv->reg_base;
1320 	para->mclk[DISP_MOD_DE] = de_drv->mclk;
1321 
1322 #if defined(CONFIG_AW_DRM_DE_V33X)
1323 	return sunxi_de_v33x_al_init(para);
1324 #elif defined(CONFIG_AW_DRM_DE_V33X)
1325 	return sunxi_de_v3x_al_init(para);
1326 #elif defined(CONFIG_AW_DRM_DE_V2X)
1327 	return sunxi_de_v2x_al_init(para);
1328 #elif defined(CONFIG_AW_DRM_DE_SUN50IW1)
1329 	return sunxi_de_sun50iw1_al_init(para);
1330 #else
1331 	"ERROR Compile!"
1332 #endif
1333 	return 0;
1334 }
1335 
1336 /*parse de dts info: reg_base/clk*/
sunxi_de_parse_dts(struct platform_device * pdev)1337 static int sunxi_de_parse_dts(struct platform_device *pdev)
1338 {
1339 	struct device_node *node;
1340 
1341 	node = pdev->dev.of_node;
1342 	if (!node) {
1343 		DRM_ERROR("get sunxi-de node err.\n ");
1344 		return -EINVAL;
1345 	}
1346 
1347 /*parse de reg_base*/
1348 	de_drv->reg_base = (uintptr_t __force)of_iomap(node, 0);
1349 	if (!de_drv->reg_base) {
1350 		DRM_ERROR("unable to map de registers\n");
1351 		return -EINVAL;
1352 	}
1353 	DRM_DEBUG_DRIVER("[SUNXI-DE]get de reg_base:0x%lx\n", de_drv->reg_base);
1354 
1355 /*get clk of de*/
1356 	de_drv->mclk = devm_clk_get(&pdev->dev, "clk_de0");
1357 	if (IS_ERR(de_drv->mclk)) {
1358 		DRM_ERROR("fail to get clk for de\n");
1359 		return -EINVAL;
1360 	}
1361 
1362 	de_drv->mclk_bus = devm_clk_get(&pdev->dev, "clk_bus_de0");
1363 	if (IS_ERR(de_drv->mclk)) {
1364 		DRM_ERROR("fail to get bus clk for de\n");
1365 		return -EINVAL;
1366 	}
1367 
1368 	de_drv->irq_no = irq_of_parse_and_map(node, 0);
1369 	if (!de_drv->irq_no) {
1370 		DRM_ERROR("irq_of_parse_and_map de irq fail\n");
1371 		return -EINVAL;
1372 	}
1373 
1374 #if defined(CONFIG_AW_DRM_DE_V33X)
1375 	if (of_property_read_u32(node, "chn_cfg_mode",
1376 		&de_drv->chn_cfg_mode) < 0) {
1377 		DRM_ERROR("failed to read chn_cfg_mode\n");
1378 		return -EINVAL;
1379 	}
1380 #endif
1381 
1382 	return 0;
1383 }
1384 
sunxi_de_probe(struct platform_device * pdev)1385 static int sunxi_de_probe(struct platform_device *pdev)
1386 {
1387 	int ret, i, lay_num;
1388 #if defined(CONFIG_AW_DRM_DE_V33X)
1389 	struct de_feat_init de_feat;
1390 #endif
1391 
1392 
1393 	DRM_INFO("[SUNXI-DE] sunxi_de_probe start\n");
1394 
1395 	de_drv->pdev = pdev;
1396 
1397 	ret = sunxi_de_parse_dts(pdev);
1398 	if (ret < 0) {
1399 		DRM_ERROR("Parse de dts failed!\n");
1400 		goto de_err;
1401 	}
1402 
1403 #if defined(CONFIG_AW_DRM_DE_V33X)
1404 	de_feat.chn_cfg_mode = de_drv->chn_cfg_mode;
1405 	de_feat_init_config(&de_feat);
1406 #else
1407 	if (de_feat_init()) {
1408 		DRM_ERROR("de_feat_init failed\n");
1409 		goto de_err;
1410 	}
1411 #endif
1412 
1413 	de_drv->de_cnt = de_feat_get_num_screens();
1414 	if ((de_drv->de_cnt <= 0) || (de_drv->de_cnt > DE_NUM_MAX)) {
1415 		DRM_ERROR("get wrong de count");
1416 		goto de_err;
1417 	}
1418 
1419 
1420 	for (i = 0; i < de_drv->de_cnt; i++) {
1421 		de_drv->hwde[i].id = i;
1422 
1423 		de_drv->hwde[i].vichannel_cnt = de_feat_get_num_vi_chns(i);
1424 		de_drv->hwde[i].uichannel_cnt = de_feat_get_num_ui_chns(i);
1425 		de_drv->hwde[i].layers_per_vichannel = 4;
1426 		de_drv->hwde[i].layers_per_uichannel = 4;
1427 	}
1428 
1429 	for (i = 0; i < de_drv->de_cnt; i++) {
1430 		lay_num = sunxi_de_get_layer_count(i);
1431 		de_drv->hwde[i].layer_config_data =
1432 			kzalloc(lay_num * sizeof(struct disp_layer_config_data),
1433 						GFP_KERNEL);
1434 		if (!de_drv->hwde[i].layer_config_data) {
1435 			DRM_ERROR("KZALLOC for disp_layer_config_data failed\n");
1436 			return -1;
1437 		}
1438 
1439 		de_drv->hwde[i].funcs = &de_funcs;
1440 	}
1441 
1442 
1443 	if (sunxi_de_init_al() < 0) {
1444 		DRM_ERROR("sunxi_de_init_al failed!\n");
1445 		goto de_err;
1446 	}
1447 
1448 	DRM_INFO("[SUNXI-DE] sunxi_de_probe end\n");
1449 	return 0;
1450 
1451 de_err:
1452 	DRM_ERROR("sunxi_de_probe FAILED\n");
1453 	return -EINVAL;
1454 }
1455 
sunxi_de_remove(struct platform_device * pdev)1456 static int sunxi_de_remove(struct platform_device *pdev)
1457 {
1458 #if defined(CONFIG_AW_DRM_DE_V33X)
1459 	return sunxi_de_v33x_al_exit();
1460 #elif defined(CONFIG_AW_DRM_DE_V3X)
1461 	return sunxi_de_v3x_al_exit();
1462 #elif defined(CONFIG_AW_DRM_DE_V2X)
1463 	return sunxi_de_v2x_al_exit();
1464 #elif defined(CONFIG_AW_DRM_DE_SUN50IW1)
1465 	return sunxi_de_sun50iw1_al_exit();
1466 #else
1467 	"ERROR Compile!"
1468 #endif
1469 
1470 	return 0;
1471 }
1472 
1473 static const struct of_device_id sunxi_de_match[] = {
1474 	{ .compatible = "allwinner,sunxi-de", },
1475 	{},
1476 };
1477 
1478 struct platform_driver sunxi_de_platform_driver = {
1479 	.probe = sunxi_de_probe,
1480 	.remove = sunxi_de_remove,
1481 	.driver = {
1482 		   .name = "de",
1483 		   .owner = THIS_MODULE,
1484 		   .of_match_table = sunxi_de_match,
1485 	},
1486 };
1487 
sunxi_de_module_init(void)1488 int sunxi_de_module_init(void)
1489 {
1490 	int ret = 0, err;
1491 	struct drv_model_info  *drv_model;
1492 
1493 	DRM_INFO("[SUNXI-DE]sunxi_de_module_init\n");
1494 
1495 	de_drv = kzalloc(sizeof(struct sunxi_de_drv), GFP_KERNEL);
1496 	if (!de_drv) {
1497 		DRM_ERROR("can NOT allocate memory for de_drv\n");
1498 		goto de_err;
1499 	}
1500 
1501 	drv_model = &de_drv->drv_model;
1502 	if (alloc_chrdev_region(&drv_model->devid, 0, 1, "de") < 0) {
1503 		DRM_ERROR("alloc_chrdev_region failed\n");
1504 		goto de_err;
1505 	}
1506 
1507 	drv_model->cdev = cdev_alloc();
1508 	if (!drv_model->cdev) {
1509 		DRM_ERROR("cdev_alloc failed\n");
1510 		goto de_err;
1511 	}
1512 
1513 	cdev_init(drv_model->cdev, NULL);
1514 	drv_model->cdev->owner = THIS_MODULE;
1515 	err = cdev_add(drv_model->cdev, drv_model->devid, 1);
1516 	if (err) {
1517 		DRM_ERROR("cdev_add major number:%d failed\n",
1518 						MAJOR(drv_model->devid));
1519 		goto de_err;
1520 	}
1521 
1522 	drv_model->sysclass = class_create(THIS_MODULE, "de");
1523 	if (IS_ERR(drv_model->sysclass)) {
1524 		DRM_ERROR("create class error\n");
1525 		goto de_err;
1526 	}
1527 
1528 	drv_model->dev = device_create(drv_model->sysclass, NULL,
1529 					drv_model->devid, NULL, "de");
1530 	if (!drv_model->dev) {
1531 		DRM_ERROR("device_create failed\n");
1532 		goto de_err;
1533 	}
1534 
1535 	ret = platform_driver_register(&sunxi_de_platform_driver);
1536 	if (ret) {
1537 		DRM_ERROR("platform_driver_register failed\n");
1538 		goto de_err;
1539 	}
1540 
1541 	ret = sysfs_create_group(&drv_model->dev->kobj, &de_attribute_group);
1542 	if (ret < 0) {
1543 		DRM_ERROR("sysfs_create_file fail!\n");
1544 		goto de_err;
1545 	}
1546 
1547 	DRM_INFO("[SUNXI-DE]sunxi_de_module_init end\n\n");
1548 	return 0;
1549 de_err:
1550 	kfree(de_drv);
1551 	DRM_ERROR("sunxi_de_module_init FAILED\n");
1552 	return -EINVAL;
1553 }
1554 
sunxi_de_module_exit(void)1555 void sunxi_de_module_exit(void)
1556 {
1557 	struct drv_model_info           *drv_model;
1558 
1559 	DRM_INFO("[SUNXI-DE]sunxi_de_module_exit\n");
1560 
1561 	drv_model = &de_drv->drv_model;
1562 	platform_driver_unregister(&sunxi_de_platform_driver);
1563 	device_destroy(drv_model->sysclass, drv_model->devid);
1564 	class_destroy(drv_model->sysclass);
1565 
1566 	cdev_del(drv_model->cdev);
1567 	kfree(de_drv);
1568 }
1569 
1570