• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*sunxi_drm_drv.c
2  *
3  * Copyright (C) 2022 Allwinnertech Co., Ltd.
4  * Authors: zhengwanyu <zhengwanyu@allwinnertech.com>
5  * Authors: hongyaobin <hongyaobin@allwinnertech.com>
6  *
7  * This program is free software; you can redistribute  it and/or modify it
8  * under  the terms of  the GNU General  Public License as published by the
9  * Free Software Foundation;  either version 2 of the  License, or (at your
10  * option) any later version.
11  */
12 
13 #include <drm/drm_crtc_helper.h>
14 #include <drm/drm_drv.h>
15 #include <drm/drm_probe_helper.h>
16 
17 #include "sunxi_drm_bootlogo.h"
18 #include "sunxi_drm_drv.h"
19 #include "sunxi_drm_crtc.h"
20 #include "sunxi_drm_encoder.h"
21 #include "sunxi_drm_connector.h"
22 #include "sunxi_drm_fb.h"
23 #include "sunxi_drm_gem.h"
24 
25 #ifdef CONFIG_DRM_FBDEV_EMULATION
26 #include "sunxi_drm_fbdev.h"
27 #endif
28 
29 #include "sunxi_drm_gem.h"
30 #include "sunxi_drm_sysfs.h"
31 #include "sunxi_drm_iommu.h"
32 
33 #include "drm_internal.h"
34 
35 #define DRIVER_NAME	"sunxi-drm"
36 #define DRIVER_DESC	"allwinnertech SoC DRM"
37 #define DRIVER_DATE	"20220517"
38 #define DRIVER_MAJOR	2
39 #define DRIVER_MINOR	0
40 
41 #define VBLANK_OFF_DELAY	50000
42 
43 static struct sunxi_drm_private sunxi_drv_prv;
44 
sunxi_drm_platform_init(struct drm_driver * ddrv,struct device * dev)45 static int sunxi_drm_platform_init(struct drm_driver *ddrv, struct device *dev)
46 {
47 	struct drm_device *ddev;
48 	struct platform_device *pdev = to_platform_device(dev);
49 	struct device_node *node = dev->of_node;
50 	int ret;
51 
52 	ddev = drm_dev_alloc(ddrv, dev);
53 	if (IS_ERR(ddev))
54 		return PTR_ERR(ddev);
55 
56 	ret = drm_dev_register(ddev, 0);
57 	if (ret)
58 		goto init_failed;
59 
60 	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
61 		 ddrv->name, ddrv->major, ddrv->minor, ddrv->patchlevel,
62 		 ddrv->date, ddev->primary->index);
63 	return 0;
64 
65 init_failed:
66 		//@TODO
67 	return ret;
68 }
69 
sunxi_drm_get_drm_device(void)70 struct drm_device *sunxi_drm_get_drm_device(void)
71 {
72 	return sunxi_drv_prv.drm_dev;
73 }
74 
75 #ifdef CONFIG_VIDEO_SUNXI_CAR_REVERSE
76 static int _force_plane_en;
77 static unsigned int active_plane_mask;
78 
sunxi_drm_get_force_plane_en(void)79 int sunxi_drm_get_force_plane_en(void)
80 {
81 	return _force_plane_en;
82 }
83 
sunxi_drm_get_num_crtc(void)84 int sunxi_drm_get_num_crtc(void)
85 {
86 	return sunxi_drm_get_crtc_count();
87 }
88 EXPORT_SYMBOL(sunxi_drm_get_num_crtc);
89 
sunxi_drm_crtc_find_attached_device(struct drm_crtc * crtc,struct drm_encoder ** enc,struct drm_connector ** conn)90 static int sunxi_drm_crtc_find_attached_device(struct drm_crtc *crtc,
91 		struct drm_encoder **enc, struct drm_connector **conn)
92 {
93 	bool find = false;
94 	struct drm_encoder *encoder;
95 	struct drm_connector *connector;
96 	struct drm_device *dev;
97 
98 	dev = crtc->dev;
99 
100 	/*find attaching encoder for crtc*/
101 	find = false;
102 	drm_for_each_encoder(encoder, dev) {
103 		if (encoder->crtc == crtc) {
104 			find = true;
105 			break;
106 		}
107 	}
108 	if (!find) {
109 		DRM_ERROR("crtc:%d has NOT attaching encoder!\n", crtc->index);
110 		return -1;
111 	}
112 	*enc = encoder;
113 
114 	/*find attaching connector for encoder*/
115 	find = false;
116 	drm_for_each_connector(connector, dev) {
117 		if (connector->encoder == encoder) {
118 			find = true;
119 			break;
120 		}
121 	}
122 	if (!find) {
123 		DRM_ERROR("encoder:%d has NOT attaching connector!\n",
124 			encoder->index);
125 		return -1;
126 	}
127 	*conn = connector;
128 
129 	return 0;
130 }
131 
disp_layer_config_convert_to_inner(struct disp_layer_config_inner * layer_inner,struct disp_layer_config * config)132 static void disp_layer_config_convert_to_inner(
133 		struct disp_layer_config_inner *layer_inner,
134 		struct disp_layer_config *config)
135 {
136 	layer_inner->enable = config->enable;
137 	layer_inner->channel = config->channel;
138 	layer_inner->layer_id = config->layer_id;
139 	layer_inner->info.mode = config->info.mode;
140 	layer_inner->info.zorder = config->info.zorder;
141 	layer_inner->info.alpha_mode = config->info.alpha_mode;
142 	layer_inner->info.alpha_value = config->info.alpha_value;
143 	memcpy(&layer_inner->info.screen_win,
144 		&config->info.screen_win, sizeof(struct disp_rect));
145 	memcpy(&layer_inner->info.fb.addr, &config->info.fb.addr,
146 		3 * sizeof(unsigned long long));
147 	memcpy(&layer_inner->info.fb.size, &config->info.fb.size,
148 		3 * sizeof(struct disp_rectsz));
149 	memcpy(&layer_inner->info.fb.align, &config->info.fb.align,
150 		3 * sizeof(unsigned int));
151 	layer_inner->info.fb.format = config->info.fb.format;
152 	layer_inner->info.fb.color_space = config->info.fb.color_space;
153 	layer_inner->info.fb.pre_multiply = config->info.fb.pre_multiply;
154 	memcpy(&layer_inner->info.fb.crop, &config->info.fb.crop,
155 		sizeof(struct disp_rect64));
156 	layer_inner->info.fb.flags = config->info.fb.flags;
157 	layer_inner->info.fb.scan = config->info.fb.scan;
158 }
159 
sunxi_drm_disable_all_active_plane(struct drm_crtc * crtc)160 static void sunxi_drm_disable_all_active_plane(struct drm_crtc *crtc)
161 {
162 	struct drm_plane *plane;
163 	struct sunxi_drm_crtc *scrtc = to_sunxi_crtc(crtc);
164 
165 	drm_for_each_plane(plane, crtc->dev) {
166 		struct disp_layer_config_data layer_config;
167 
168 		if (plane->crtc != crtc)
169 			continue;
170 
171 		if (!plane->state)
172 			continue;
173 
174 		memset(&layer_config, 0,
175 			sizeof(struct disp_layer_config_data));
176 		layer_config.flag = LAYER_ALL_DIRTY;
177 		layer_config.config.enable = false;
178 
179 		layer_config.config.channel =
180 			scrtc->hw_funcs->get_layer_channel_id(
181 				scrtc->crtc_id, plane->index);
182 		layer_config.config.layer_id =
183 			scrtc->hw_funcs->get_layer_id_within_chanel(
184 				scrtc->crtc_id, plane->index);
185 
186 		if (scrtc->hw_funcs->single_layer_apply(scrtc->crtc_id,
187 					&layer_config) < 0) {
188 			DRM_ERROR("sunxi_de single layer_apply failed\n");
189 		} else {
190 			DRM_DEBUG_DRIVER("%s success\n", __func__);
191 		}
192 	}
193 }
194 
sunxi_drm_force_set_plane(int crtc_id,struct disp_layer_config * config,unsigned int plane_num)195 int sunxi_drm_force_set_plane(int crtc_id, struct disp_layer_config *config,
196 			unsigned int plane_num)
197 {
198 	int i = 0, irq_no;
199 	bool enable;
200 
201 	unsigned int hdisplay, vdisplay, vrefresh;
202 	struct disp_video_timings *p_info = NULL;
203 	unsigned int tv_mode = 0;
204 
205 	struct disp_manager_data data;
206 	struct disp_manager_info *info = &data.config;
207 	struct disp_layer_config_data layer_data[16];
208 	struct disp_layer_config_inner *layer_inner;
209 
210 	struct drm_device *dev;
211 	struct drm_encoder *encoder;
212 	struct sunxi_drm_encoder *sencoder;
213 	struct drm_connector *conn;
214 	struct sunxi_drm_connector *sconn;
215 	struct sunxi_drm_crtc *scrtc = sunxi_drm_crtc_get_crtc(crtc_id);
216 	struct drm_crtc_state *crtc_state = NULL;
217 
218 	dev = scrtc->crtc.dev;
219 	memset(&data, 0, sizeof(struct disp_manager_data));
220 	memset(layer_data, 0,
221 		16 * sizeof(struct disp_layer_config_data));
222 
223 	_force_plane_en = 1;
224 
225 	crtc_state = scrtc->crtc.state;
226 	if (!crtc_state) {
227 		DRM_ERROR("crtc:%d has NOT set!\n", crtc_id);
228 		return;
229 	}
230 
231 	mutex_lock(&dev->mode_config.mutex);
232 
233 	if (sunxi_drm_crtc_find_attached_device(&scrtc->crtc,
234 		&encoder, &conn) < 0) {
235 		DRM_INFO("[warning] crtc:%d has NOT been set\n",
236 			scrtc->crtc_id);
237 		return -1;
238 	}
239 	sencoder = to_sunxi_encoder(encoder);
240 	sconn = to_sunxi_connector(conn);
241 	/*attaching connector type for tcon*/
242 	sencoder->hw_funcs =
243 		sunxi_tcon_attach_connector_type(sencoder->encoder_id,
244 						sconn->type);
245 	mutex_unlock(&dev->mode_config.mutex);
246 
247 	enable = scrtc->hw_funcs->is_enable(crtc_id);
248 	if (!enable) {
249 	/*irq register*/
250 		sencoder->use_irq =
251 			sencoder->hw_funcs->is_use_irq(sencoder->encoder_id);
252 		sencoder->irq_no =
253 			sencoder->hw_funcs->get_irq_no(sencoder->encoder_id);
254 
255 		if (sconn->use_irq)
256 			irq_no = sconn->irq_no;
257 		else if (sencoder->use_irq)
258 			irq_no = sencoder->irq_no;
259 		else
260 			DRM_INFO("WARN: NO irq for tcon%d and lcd%d\n",
261 				sencoder->encoder_id, sconn->con_id);
262 		if (scrtc->irq_register(scrtc, irq_no) < 0) {
263 			DRM_ERROR("sunxi_drm_crtc_irq_register failed\n");
264 			return -1;
265 		}
266 
267 	/*setting params for sunxi-crtc and enable it*/
268 		data.flag = MANAGER_ALL_DIRTY;
269 		info->size.x = 0;
270 		info->size.y = 0;
271 
272 		info->hwdev_index = encoder->index;
273 
274 		sconn->get_init_resolution(sconn,
275 			&hdisplay, &vdisplay, &vrefresh);
276 		info->size.width = hdisplay;
277 		info->size.height = vdisplay;
278 
279 		info->color_space = DISP_BT601_F;
280 
281 		if (sconn->get_work_mode) {
282 			struct sunxi_connector_work_mode conn_work_mode;
283 
284 			sconn->get_work_mode(sconn, &conn_work_mode);
285 
286 			if (conn_work_mode.color_fmt == COLOR_FMT_RGB444)
287 				info->cs = DISP_CSC_TYPE_RGB;
288 			else if (conn_work_mode.color_fmt == COLOR_FMT_YUV444)
289 				info->cs = DISP_CSC_TYPE_YUV444;
290 			else if (conn_work_mode.color_fmt == COLOR_FMT_YUV422)
291 				info->cs = DISP_CSC_TYPE_YUV422;
292 			else if (conn_work_mode.color_fmt == COLOR_FMT_YUV420)
293 				info->cs = DISP_CSC_TYPE_YUV420;
294 			else {
295 				info->cs = DISP_CSC_TYPE_RGB;
296 				DRM_ERROR("sunxi connector:%d working mode hasn't been set\n",
297 					sconn->con_id);
298 			}
299 		} else {
300 			info->cs = DISP_CSC_TYPE_RGB;
301 		}
302 
303 
304 		if (info->cs == DISP_CSC_TYPE_RGB)
305 			info->color_range = DISP_COLOR_RANGE_0_255;
306 		else
307 			info->color_range = DISP_COLOR_RANGE_16_235;
308 
309 		info->conn_type = sconn->type;
310 
311 		info->enable = true;
312 		info->disp_device = crtc_id;
313 
314 		info->blank = false;
315 		info->de_freq = scrtc->hw_funcs->get_freq(crtc_id);
316 		info->device_fps = vrefresh;
317 		info->eotf = DISP_EOTF_GAMMA22;
318 		info->data_bits = DISP_DATA_8BITS;
319 
320 		scrtc->hw_funcs->enable(crtc_id, &data);
321 
322 	/*set encoder and connector*/
323 		if (kstrtou32(crtc_state->mode.name, 10, &tv_mode)) {
324 			DRM_ERROR("Get tv mode fail!\n");
325 			return;
326 		}
327 
328 		if (sconn->get_video_timing)
329 			sconn->get_video_timing(p_info, tv_mode);
330 		sencoder->hw_funcs->set(scrtc->crtc_id,
331 					sencoder->encoder_id,
332 					sconn->type_id, p_info, tv_mode);
333 		sconn->enable(sconn, tv_mode);
334 	} else {
335 		sunxi_drm_disable_all_active_plane(&scrtc->crtc);
336 	}
337 
338 /*set plane*/
339 	for (i = 0; i < plane_num; i++) {
340 		layer_data[i].flag = LAYER_ALL_DIRTY;
341 
342 		layer_inner = &layer_data[i].config;
343 		disp_layer_config_convert_to_inner(layer_inner,
344 						&config[i]);
345 		active_plane_mask |=
346 			1 << (layer_inner->channel * 4 + layer_inner->layer_id);
347 	}
348 
349 	scrtc->hw_funcs->multi_layers_apply(scrtc->crtc_id,
350 		layer_data, plane_num);
351 
352 	atomic_set(&scrtc->update, 1);
353 
354 	return 0;
355 }
356 EXPORT_SYMBOL(sunxi_drm_force_set_plane);
357 
358 /*
359   * exit force_set_plane and restore drm setings set by user space app
360   */
sunxi_drm_force_set_plane_exit(int crtc_id)361 void sunxi_drm_force_set_plane_exit(int crtc_id)
362 {
363 	struct sunxi_drm_crtc *scrtc = sunxi_drm_crtc_get_crtc(crtc_id);
364 	const struct drm_crtc_helper_funcs *crtc_funcs = scrtc->crtc.helper_private;
365 	struct drm_crtc_state *crtc_state = NULL;
366 	struct drm_plane *plane;
367 	struct drm_plane_state *plane_state = NULL;
368 
369 	if (!_force_plane_en)
370 		return;
371 	_force_plane_en = 0;
372 
373 	crtc_state = scrtc->crtc.state;
374 	if (!crtc_state) {
375 		DRM_ERROR("crtc:%d has NOT set!\n", crtc_id);
376 		return;
377 	}
378 
379 	drm_for_each_plane(plane, scrtc->crtc.dev) {
380 		struct disp_layer_config_data layer_config;
381 
382 		if (!(active_plane_mask & (1 << plane->index)))
383 			continue;
384 
385 		memset(&layer_config, 0,
386 			sizeof(struct disp_layer_config_data));
387 
388 		layer_config.config.channel =
389 			scrtc->hw_funcs->get_layer_channel_id(
390 				crtc_id, plane->index);
391 		layer_config.config.layer_id =
392 			scrtc->hw_funcs->get_layer_id_within_chanel(
393 				crtc_id, plane->index);
394 
395 		layer_config.flag = LAYER_ALL_DIRTY;
396 		layer_config.config.enable = false;
397 
398 		if (scrtc->hw_funcs->single_layer_apply(scrtc->crtc_id,
399 					&layer_config) < 0) {
400 			DRM_ERROR("sunxi_de single layer_apply failed\n");
401 		} else {
402 			DRM_DEBUG_DRIVER("%s success\n", __func__);
403 		}
404 	}
405 
406 	drm_for_each_plane(plane, scrtc->crtc.dev) {
407 		const struct drm_plane_helper_funcs *plane_funcs;
408 
409 		if (crtc_state->plane_mask & (1 << plane->index)) {
410 			plane_state = plane->state;
411 			if (!plane_state)
412 				continue;
413 
414 			DRM_INFO("SET plane:%d\n", plane->index);
415 			plane_funcs = plane->helper_private;
416 			plane_funcs->atomic_update(plane, NULL);
417 		}
418 	}
419 
420 	atomic_set(&scrtc->update, 1);
421 
422 	crtc_funcs->enable(&scrtc->crtc);
423 }
424 EXPORT_SYMBOL(sunxi_drm_force_set_plane_exit);
425 
426 #endif
427 
sunxi_drm_enable_vblank(struct drm_device * dev,unsigned int pipe)428 int sunxi_drm_enable_vblank(struct drm_device *dev, unsigned int pipe)
429 {
430 	return 0;
431 }
432 
sunxi_drm_disable_vblank(struct drm_device * dev,unsigned int pipe)433 void sunxi_drm_disable_vblank(struct drm_device *dev, unsigned int pipe)
434 {
435 	return;
436 }
437 
sunxi_drm_vblank_counter(struct drm_device * dev,unsigned int pipe)438 u32 sunxi_drm_vblank_counter(struct drm_device *dev, unsigned int pipe)
439 {
440 	return 0;
441 }
442 
443 /*
444  * bootlogo processing for crtc/connector state:
445  * 1.create a state for connector and initial its members with booting information;
446  * 2.create a state for crtc and initial its members with booting information;
447  */
sunxi_drm_smooth_set_state(struct drm_device * dev)448 static int sunxi_drm_smooth_set_state(struct drm_device *dev)
449 {
450 	struct drm_display_mode *mode;
451 	struct drm_crtc *crtc;
452 	struct sunxi_drm_crtc *scrtc;
453 	struct sunxi_drm_connector *sconn =
454 		sunxi_drm_connector_get_connector(0);
455 	struct drm_connector *conn = &sconn->connector;
456 
457 	if (!conn->state) {
458 		conn->state
459 			= kzalloc(sizeof(struct drm_connector_state),
460 							GFP_KERNEL);
461 		if (!conn->state) {
462 			DRM_ERROR("allocate mem for "
463 				"drm_connector_state failed\n");
464 			return -1;
465 		}
466 	}
467 
468 	/*sunxi_drm_fbdev_initial_config()
469 	has been do a default attachment for crtc/encoder/connector*/
470 	if (!conn->encoder) {
471 		DRM_ERROR("connector has NOT attched to a encoder\n");
472 		return -1;
473 	}
474 	if (!conn->encoder->crtc) {
475 		DRM_ERROR("encoder has NOT attached to a crtc\n");
476 		return -1;
477 	}
478 
479 	conn->state->best_encoder = conn->encoder;
480 	conn->state->crtc = conn->encoder->crtc;
481 	conn->state->connector = conn;
482 
483 	crtc = conn->encoder->crtc;
484 	scrtc = to_sunxi_crtc(crtc);
485 
486 	if (!crtc->state) {
487 		crtc->state =
488 			kzalloc(sizeof(struct drm_crtc_state), GFP_KERNEL);
489 		if (!crtc->state) {
490 			DRM_ERROR("allocate mem for drm_crtc_state "
491 						"failed\n");
492 			return -1;
493 		}
494 	}
495 
496 	crtc->state->crtc = crtc;
497 	crtc->state->enable = 1;
498 	crtc->state->active = 1;
499 	crtc->state->plane_mask = 0x10000000;
500 	crtc->state->connector_mask = 0x1;
501 	crtc->state->encoder_mask = 1 << conn->encoder->index;
502 
503 	list_for_each_entry(mode, &conn->modes, head) {
504 		memcpy(&crtc->state->mode, mode,
505 			sizeof(struct drm_display_mode));
506 		drm_mode_copy(&crtc->state->adjusted_mode, mode);
507 	}
508 
509 	return 0;
510 }
511 
512 
sunxi_drm_is_need_smooth_boot(void)513 bool sunxi_drm_is_need_smooth_boot(void)
514 {
515 	/*fb_base got from DTS is the judgement*/
516 	return sunxi_drv_prv.boot_disp ? true : false;
517 }
518 
sunxi_drm_smooth_boot(struct drm_device * dev)519 static int sunxi_drm_smooth_boot(struct drm_device *dev)
520 {
521 	int ret;
522 
523 	struct sunxi_drm_crtc *scrtc;
524 	struct drm_encoder *enc;
525 	struct sunxi_drm_encoder *senc;
526 	struct sunxi_drm_connector *sconn;
527 
528 	scrtc = sunxi_drm_crtc_get_crtc(0);
529 	sconn = sunxi_drm_connector_get_connector(0);
530 
531 	enc = sconn->connector.encoder;
532 	if (!enc) {
533 		DRM_ERROR("crtc:0 has NO attached encoder\n");
534 		return -1;
535 	}
536 	senc = to_sunxi_encoder(enc);
537 
538 	ret = sunxi_drm_smooth_set_state(dev);
539 	if (ret < 0) {
540 		DRM_ERROR("sunxi_drm_smooth_set_state failed\n");
541 		return -1;
542 	}
543 
544 	scrtc->sw_enable(scrtc);
545 	senc->sw_enable(senc);
546 
547 	return 0;
548 }
549 
550 /*this func is used to decide bpp of fbdev fb */
sunxi_drm_get_init_bpp(void)551 unsigned int sunxi_drm_get_init_bpp(void)
552 {
553 #ifdef CONFIG_DRM_FBDEV_EMULATION
554 	if (sunxi_drv_prv.bootlogo.bpp)
555 		return sunxi_drv_prv.bootlogo.bpp;
556 #endif
557 
558 	return 32;
559 }
560 
561 /*this func is used to decide width of fbdev fb */
sunxi_drm_get_init_width(void)562 unsigned int sunxi_drm_get_init_width(void)
563 {
564 	unsigned int w, h, f;
565 	struct sunxi_drm_connector *sconn
566 			= sunxi_drm_connector_get_connector(0);
567 
568 #ifdef CONFIG_DRM_FBDEV_EMULATION
569 	if (sunxi_drv_prv.bootlogo.width)
570 		return sunxi_drv_prv.bootlogo.width;
571 #endif
572 
573 	sconn->get_init_resolution(sconn, &w, &h, &f);
574 	return w;
575 }
576 
577 /*this func is used to decide height of fbdev fb*/
sunxi_drm_get_init_height(void)578 unsigned int sunxi_drm_get_init_height(void)
579 {
580 	unsigned int w, h, f;
581 	struct sunxi_drm_connector *sconn
582 			= sunxi_drm_connector_get_connector(0);
583 
584 #ifdef CONFIG_DRM_FBDEV_EMULATION
585 	if (sunxi_drv_prv.bootlogo.height)
586 		return sunxi_drv_prv.bootlogo.height;
587 #endif
588 
589 	sconn->get_init_resolution(sconn, &w, &h, &f);
590 	return h;
591 }
592 
sunxi_drm_get_connector_type(int i)593 unsigned int sunxi_drm_get_connector_type(int i)
594 {
595 	if (i >= sunxi_drv_prv.connector_num) {
596 		DRM_ERROR("connector:%d is out of range!\n", i);
597 		return 0;
598 	}
599 
600 	return sunxi_drv_prv.connector_type[i];
601 }
602 
sunxi_drm_get_connector_mode(int i)603 char *sunxi_drm_get_connector_mode(int i)
604 {
605 	if (i >= sunxi_drv_prv.connector_num) {
606 		DRM_ERROR("connector:%d is out of range!\n", i);
607 		return NULL;
608 	}
609 
610 	return (char *)&sunxi_drv_prv.connector_mode[i][0];
611 }
612 
sunxi_drm_get_connector_count(void)613 unsigned int sunxi_drm_get_connector_count(void)
614 {
615 	return sunxi_drv_prv.connector_num;
616 }
617 
sunxi_drm_init(struct drm_device * dev)618 static int sunxi_drm_init(struct drm_device *dev)
619 {
620 	if (sunxi_drm_crtc_init(dev) < 0) {
621 		DRM_ERROR("sunxi_drm_crtc_init failed\n");
622 		goto crtc_err;
623 	}
624 
625 	if (sunxi_drm_encoder_init(dev) < 0) {
626 		DRM_ERROR("sunxi_drm_encoder_init failed\n");
627 		goto enc_err;
628 	}
629 
630 	if (sunxi_drm_connector_init(dev) < 0) {
631 		DRM_ERROR("sunxi_drm_connector_init failed\n");
632 		goto con_err;
633 	}
634 
635 #ifdef CONFIG_DRM_FBDEV_EMULATION
636 	if (sunxi_drm_fbdev_init(dev) < 0) {
637 		DRM_ERROR("sunxi_drm_fbdev_init failed\n");
638 		goto con_err;
639 	}
640 #endif
641 
642 	return 0;
643 
644 con_err:
645 	sunxi_drm_connector_exit(dev);
646 enc_err:
647 	sunxi_drm_encoder_exit(dev);
648 crtc_err:
649 	sunxi_drm_crtc_exit(dev);
650 	DRM_ERROR("sunxi drm init failed\n");
651 	return -1;
652 }
653 
sunxi_drm_destroy(struct drm_device * dev)654 void sunxi_drm_destroy(struct drm_device *dev)
655 {
656 #ifdef CONFIG_DRM_FBDEV_EMULATION
657 	sunxi_drm_fbdev_exit(dev);
658 #endif
659 	sunxi_drm_connector_exit(dev);
660 	sunxi_drm_encoder_exit(dev);
661 	sunxi_drm_crtc_exit(dev);
662 }
663 
sunxi_drm_output_poll_changed(struct drm_device * dev)664 static void sunxi_drm_output_poll_changed(struct drm_device *dev)
665 {
666 #ifdef CONFIG_DRM_FBDEV_EMULATION
667 	sunxi_drm_fbdev_output_poll_changed(dev);
668 #else
669 	/*struct drm_crtc *crtc;
670 	struct drm_encoder *encoder;
671 	bool find = false;
672 
673 	drm_for_each_crtc(crtc, dev) {
674 		if (!crtc->state)
675 			continue;
676 		if (crtc->state->active)
677 			continue;
678 
679 		crtc->helper_private->enable(crtc);
680 
681 		drm_for_each_encoder(encoder, dev) {
682 			if (encoder->crtc == crtc) {
683 				find = true;
684 				break;
685 			}
686 		}
687 
688 		if (!find) {
689 			DRM_ERROR("can NOT find an \n");
690 		}
691 	}*/
692 #endif
693 	return;
694 }
695 
696 static const struct drm_mode_config_funcs sunxi_drm_mode_config_funcs = {
697 	.atomic_check		= drm_atomic_helper_check,
698 	.atomic_commit		= drm_atomic_helper_commit,
699 	.output_poll_changed	= sunxi_drm_output_poll_changed,
700 	.fb_create		= sunxi_drm_fb_create,
701 };
702 
sunxi_drm_mode_config_init(struct drm_device * dev)703 void sunxi_drm_mode_config_init(struct drm_device *dev)
704 {
705 	dev->mode_config.min_width = 0;
706 	dev->mode_config.min_height = 0;
707 
708 	/* max_width be decided by the de bufferline */
709 	dev->mode_config.max_width = 8192;
710 	dev->mode_config.max_height = 8192;
711 
712 	dev->mode_config.funcs = &sunxi_drm_mode_config_funcs;
713 
714 }
715 
sunxi_drm_init_iommu(struct drm_device * drm_dev)716 static int sunxi_drm_init_iommu(struct drm_device *drm_dev)
717 {
718 	int ret;
719 	struct sunxi_drm_private *priv = drm_dev->dev_private;
720 
721 	if (!IS_ENABLED(CONFIG_AW_IOMMU) || !IS_ENABLED(CONFIG_DRM_AW_IOMMU))
722 		return 0;
723 
724 	/* create common IOMMU mapping for all devices attached to SUNXI DRM */
725 	ret = sunxi_drm_create_iommu_mapping(drm_dev);
726 	if (ret < 0) {
727 		DRM_ERROR("failed to create iommu mapping.\n");
728 		return ret;
729 	}
730 
731 	return 0;
732 }
733 
sunxi_drm_load(struct drm_device * dev,unsigned long flags)734 static int sunxi_drm_load(struct drm_device *dev, unsigned long flags)
735 {
736 	int ret;
737 
738 	DRM_INFO("[DRM-DRV]%s start\n", __func__);
739 
740 	dev->dev_private = (void *)&sunxi_drv_prv;
741 	sunxi_drv_prv.drm_dev = dev;
742 
743 	if (sunxi_drm_init_iommu(dev)) {
744 		DRM_ERROR("sunxi_drm_init_iommu failed!\n");
745 		goto load_err;
746 	}
747 
748 	drm_mode_config_init(dev);
749 	sunxi_drm_mode_config_init(dev);
750 
751 	if (sunxi_drm_init(dev)) {
752 		DRM_ERROR("failed to initialize sunxi drm dev.\n");
753 		goto load_err;
754 	}
755 
756 	dev->irq_enabled = 1;
757 	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
758 	if (ret) {
759 		DRM_ERROR("failed to init vblank.\n");
760 		goto load_err;
761 	}
762 
763 	/* init kms poll for handling hpd */
764 	drm_kms_helper_poll_init(dev);
765 	return 0;
766 
767 load_err:
768 	sunxi_drm_destroy(dev);
769 	drm_mode_config_cleanup(dev);
770 	sunxi_drv_prv.drm_dev = NULL;
771 	DRM_ERROR("LOAD failed\n");
772 	return -1;
773 }
774 
sunxi_drm_unload(struct drm_device * dev)775 static void sunxi_drm_unload(struct drm_device *dev)
776 {
777 	//drm_vblank_cleanup(dev);
778 	sunxi_drm_destroy(dev);
779 	drm_mode_config_cleanup(dev);
780 }
781 
782 static struct drm_ioctl_desc sunxi_ioctls[] = {
783 	DRM_IOCTL_DEF_DRV(SUNXI_GEM_CREATE, sunxi_drm_gem_create_ioctl,
784 			DRM_AUTH | DRM_RENDER_ALLOW),
785 	DRM_IOCTL_DEF_DRV(SUNXI_SET_ENHANCE, sunxi_drm_crtc_set_enhance_ioctl,
786 			DRM_AUTH | DRM_RENDER_ALLOW),
787 	DRM_IOCTL_DEF_DRV(SUNXI_GET_ENHANCE, sunxi_drm_crtc_get_enhance_ioctl,
788 			DRM_AUTH | DRM_RENDER_ALLOW),
789 	DRM_IOCTL_DEF_DRV(SUNXI_SET_SMBL, sunxi_drm_crtc_set_smbl_ioctl,
790 			DRM_AUTH | DRM_RENDER_ALLOW),
791 	DRM_IOCTL_DEF_DRV(SUNXI_GET_SMBL, sunxi_drm_crtc_get_smbl_ioctl,
792 			DRM_AUTH | DRM_RENDER_ALLOW),
793 	DRM_IOCTL_DEF_DRV(SUNXI_GEM_FD_TO_PHYADDR, sunxi_drm_gem_get_phyaddr_ioctl,
794 			DRM_UNLOCKED),
795 };
796 
797 static const struct file_operations sunxi_drm_driver_fops = {
798 	.owner = THIS_MODULE,
799 	.open = drm_open,
800 	.mmap = sunxi_drm_gem_mmap,
801 	.poll = drm_poll,
802 	.read = drm_read,
803 	.unlocked_ioctl	= drm_ioctl,
804 #ifdef CONFIG_COMPAT
805 	.compat_ioctl = drm_compat_ioctl,
806 #endif
807 	.release = drm_release,
808 };
809 
810 static struct drm_driver sunxi_drm_driver = {
811 	.driver_features = DRIVER_HAVE_IRQ | DRIVER_MODESET |
812 		DRIVER_GEM | DRIVER_ATOMIC,
813 	.ioctls = sunxi_ioctls,
814 	.fops = &sunxi_drm_driver_fops,
815 	.name = DRIVER_NAME,
816 	.desc = DRIVER_DESC,
817 	.date = DRIVER_DATE,
818 	.major = DRIVER_MAJOR,
819 	.minor = DRIVER_MINOR,
820 	.load = sunxi_drm_load,
821 	.unload = sunxi_drm_unload,
822 
823 	/*gem*/
824 	.gem_vm_ops = &sunxi_drm_gem_vm_ops,
825 	.gem_free_object_unlocked = sunxi_drm_gem_free_object,
826 	.dumb_create = sunxi_drm_gem_dumb_create,
827 	.dumb_map_offset = sunxi_drm_gem_dumb_map_offset,
828 	.dumb_destroy = drm_gem_dumb_destroy,
829 
830 	/*prime*/
831 	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
832 	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
833 	.gem_prime_export = drm_gem_prime_export,
834 	.gem_prime_import = drm_gem_prime_import,
835 	.gem_prime_get_sg_table = sunxi_drm_gem_prime_get_sg_table,
836 	.gem_prime_import_sg_table = sunxi_drm_gem_prime_import_sg_table,
837 	.gem_prime_mmap = sunxi_drm_gem_prime_mmap,
838 
839 	/*vblank*/
840 	.enable_vblank = sunxi_drm_enable_vblank,
841 	.disable_vblank = sunxi_drm_disable_vblank,
842 	.get_vblank_counter = sunxi_drm_vblank_counter,
843 };
844 
sunxi_drm_parse_dts(struct device_node * np)845 static int sunxi_drm_parse_dts(struct device_node *np)
846 {
847 	int ret = 0, i;
848 	unsigned char string[30] = { 0 };
849 #ifdef CONFIG_DRM_FBDEV_EMULATION
850 	unsigned int boot_disp;
851 #endif
852 
853 	/*read bootlogo physical address*/
854 	ret = of_property_read_u32(np, "fb_base",
855 				&sunxi_drv_prv.fb_base);
856 	if (ret < 0) {
857 		DRM_ERROR("Parse DTS-info fb_base failed!\n");
858 		return ret;
859 	}
860 
861 	if (sunxi_drv_prv.fb_base == 0) {
862 		const char *boot_fb;
863 
864 		ret = of_property_read_string(np, "boot_fb0",
865 				&boot_fb);
866 		if (ret < 0) {
867 			DRM_ERROR("There is NO boot_fb0\n");
868 			return ret;
869 		}
870 
871 		strcpy(sunxi_drv_prv.boot_fb, (char *)boot_fb);
872 	}
873 
874 #ifdef CONFIG_DRM_FBDEV_EMULATION
875 	/*read that if there is a bootlogo output during bootloader*/
876 	ret = of_property_read_u32(np, "boot_disp", &boot_disp);
877 	if (ret < 0) {
878 		DRM_ERROR("Parse DTS-info boot_disp failed!\n");
879 		return ret;
880 	}
881 	sunxi_drv_prv.boot_disp = boot_disp ? true : false;
882 #endif
883 
884 	for (i = 0; i < MAX_CONNECTOR_COUNT; i++) {
885 		const char *mode_name;
886 
887 		sprintf(string, "connector%d_output_type", i);
888 		ret = of_property_read_u32(np, string,
889 				&sunxi_drv_prv.connector_type[i]);
890 		if (ret < 0 || (!sunxi_drv_prv.connector_type[i])) {
891 			DRM_INFO("WARN:Parse DTS-info connector%d_output_type failed!\n",
892 					i);
893 			break;
894 		}
895 
896 		sprintf(string, "connector%d_output_mode", i);
897 		ret = of_property_read_string(np, string, &mode_name);
898 		if (ret < 0) {
899 			DRM_ERROR("Parse DTS-info connector%d_output_mode failed!\n",
900 					i);
901 			break;
902 		}
903 
904 		strcpy(sunxi_drv_prv.connector_mode[i], (char *)mode_name);
905 		/*memcpy(sunxi_drv_prv.connector_mode[i], mode_name, 20);
906 
907 		DRM_INFO("Parse DTS-info:%s result:%s   - %c %c %c\n",
908 			string, sunxi_drv_prv.connector_mode[i],
909 			mode_name[0], mode_name[1], mode_name[2]);*/
910 
911 		sunxi_drv_prv.connector_num++;
912 	}
913 
914 	DRM_DEBUG_DRIVER("SUNXI DRM DTS INFO:\n");
915 	DRM_DEBUG_DRIVER("fb_base:%u\n", sunxi_drv_prv.fb_base);
916 	DRM_DEBUG_DRIVER("boot_disp:%d\n", sunxi_drv_prv.boot_disp);
917 	DRM_DEBUG_DRIVER("connector_num:%d\n", sunxi_drv_prv.connector_num);
918 	for (i = 0; i < sunxi_drv_prv.connector_num; i++) {
919 		DRM_DEBUG_DRIVER("connector%d_type:%u\n",
920 					i, sunxi_drv_prv.connector_type[i]);
921 		DRM_DEBUG_DRIVER("connector%d_mode:%s\n",
922 					i, sunxi_drv_prv.connector_mode[i]);
923 	}
924 
925 	return 0;
926 }
927 
sunxi_drm_platform_probe(struct platform_device * pdev)928 static int sunxi_drm_platform_probe(struct platform_device *pdev)
929 {
930 	int ret;
931 	struct device_node *np;
932 
933 	DRM_INFO("[DRM-DRV]%s start\n", __func__);
934 
935 	memset(&sunxi_drv_prv, 0, sizeof(struct sunxi_drm_private));
936 	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(64);
937 	sunxi_drm_driver.num_ioctls = ARRAY_SIZE(sunxi_ioctls);
938 	sunxi_drv_prv.pdev = pdev;
939 	np = pdev->dev.of_node;
940 
941 	ret = sunxi_drm_parse_dts(np);
942 	if (ret < 0) {
943 		DRM_ERROR("sunxi_drm_parse_dts FAILED!\n");
944 		goto drm_err;
945 	}
946 
947 #ifdef CONFIG_DRM_FBDEV_EMULATION
948 	/*parse bootlogo bmp file*/
949 	if (sunxi_drv_prv.fb_base) {
950 		ret = sunxi_drm_parse_bmp_header(&sunxi_drv_prv.bootlogo_bmp_header,
951 							sunxi_drv_prv.fb_base);
952 		if (ret < 0) {
953 			DRM_INFO("parse bmp bootlogo failed, phy_addr:0x%x\n",
954 					sunxi_drv_prv.fb_base);
955 			goto drm_err;
956 		}
957 
958 		sunxi_drm_get_bootlogoinfo_from_bmp_header(
959 				&sunxi_drv_prv.bootlogo,
960 				&sunxi_drv_prv.bootlogo_bmp_header,
961 				sunxi_drv_prv.fb_base);
962 	} else {
963 		sunxi_drm_get_bootlogoinfo_from_dts_info(&sunxi_drv_prv.bootlogo,
964 			sunxi_drv_prv.boot_fb);
965 	}
966 #endif
967 
968 	ret = sunxi_drm_platform_init(&sunxi_drm_driver, &pdev->dev);
969 	if (ret < 0) {
970 		DRM_ERROR("sunxi_drm_platform_init\n");
971 		goto drm_err;
972 	}
973 
974 #ifdef CONFIG_DRM_FBDEV_EMULATION
975 	/*if (sunxi_drv_prv.bootlogo.phy_addr) {
976 		ret = sunxi_drm_fbdev_copy_bootlogo(
977 			sunxi_drv_prv.drm_dev, &sunxi_drv_prv.bootlogo);
978 		if (ret < 0) {
979 			DRM_ERROR("fbdev copy bootlogo failed\n");
980 			goto drm_err;
981 		}
982 	}*/
983 #endif
984 
985 	if (sunxi_drm_is_need_smooth_boot()) {
986 		if (sunxi_drm_smooth_boot(sunxi_drv_prv.drm_dev) < 0) {
987 			DRM_ERROR("sunxi_drm smooth booting failed\n");
988 			goto drm_err;
989 		}
990 	}
991 
992 	DRM_INFO("[DRM-DRV]%s end\n", __func__);
993 	return 0;
994 
995 drm_err:
996 	DRM_INFO("[DRM-DRV]%s failed\n", __func__);
997 	return -1;
998 }
999 
sunxi_drm_platform_remove(struct platform_device * pdev)1000 static int sunxi_drm_platform_remove(struct platform_device *pdev)
1001 {
1002 	DRM_DEBUG_DRIVER("[%d]\n", __LINE__);
1003 
1004 	drm_put_dev(dev_get_drvdata(&pdev->dev));
1005 
1006 	return 0;
1007 }
1008 
1009 #ifdef CONFIG_PM_RUNTIME
sunxi_runtime_suspend(struct device * dev)1010 static int sunxi_runtime_suspend(struct device *dev)
1011 {
1012 	return 0;
1013 }
1014 
sunxi_runtime_resume(struct device * dev)1015 static int sunxi_runtime_resume(struct device *dev)
1016 {
1017 	return 0;
1018 }
1019 
sunxi_runtime_idle(struct device * dev)1020 static int sunxi_runtime_idle(struct device *dev)
1021 {
1022 	return 0;
1023 }
1024 #endif
1025 
sunxi_drm_suspend(struct device * dev)1026 static int sunxi_drm_suspend(struct device *dev)
1027 {
1028 	struct drm_device *device = sunxi_drv_prv.drm_dev;
1029 	struct drm_connector *conct = NULL;
1030 
1031 	if ((dev != device->dev)
1032 		|| (device == NULL)) {
1033 		DRM_ERROR("devices are different or drm_device is NULL\n");
1034 		return 0;
1035 	}
1036 
1037 	drm_modeset_lock_all(device);
1038 	list_for_each_entry(conct, &device->mode_config.connector_list, head)
1039 		conct->funcs->dpms(conct, DRM_MODE_DPMS_OFF);
1040 	drm_modeset_unlock_all(device);
1041 
1042 	return 0;
1043 }
1044 
sunxi_drm_resume(struct device * dev)1045 static int sunxi_drm_resume(struct device *dev)
1046 {
1047 	struct drm_device *device = sunxi_drv_prv.drm_dev;
1048 	struct drm_connector *conct = NULL;
1049 
1050 	if ((dev != device->dev)
1051 		|| (device == NULL)) {
1052 		DRM_ERROR("devices are different or drm_device is NULL\n");
1053 		return 0;
1054 	}
1055 
1056 
1057 	drm_modeset_lock_all(device);
1058 	list_for_each_entry(conct, &device->mode_config.connector_list, head)
1059 		conct->funcs->dpms(conct, DRM_MODE_DPMS_ON);
1060 	drm_modeset_unlock_all(device);
1061 
1062 	return 0;
1063 }
1064 
1065 
1066 static const struct dev_pm_ops sunxi_drm_runtime_pm_ops = {
1067 #ifdef CONFIG_PM_RUNTIME
1068 	.runtime_suspend = sunxi_runtime_suspend,
1069 	.runtime_resume = sunxi_runtime_resume,
1070 	.runtime_idle = sunxi_runtime_idle,
1071 #endif
1072 	.suspend = sunxi_drm_suspend,
1073 	.resume = sunxi_drm_resume,
1074 };
1075 
1076 static const struct of_device_id sunxi_of_match[] = {
1077 	{ .compatible = "allwinner,sunxi-drm", },
1078 	{},
1079 };
1080 MODULE_DEVICE_TABLE(of, sunxi_of_match);
1081 
1082 static struct platform_driver sunxi_drm_platform_driver = {
1083 	.probe = sunxi_drm_platform_probe,
1084 	.remove = sunxi_drm_platform_remove,
1085 	.driver = {
1086 		.owner = THIS_MODULE,
1087 		.name = "sunxi-drm",
1088 		.of_match_table = sunxi_of_match,
1089 		.pm = &sunxi_drm_runtime_pm_ops,
1090 	},
1091 };
1092 
1093 
sunxi_drm_drv_init(void)1094 static int __init sunxi_drm_drv_init(void)
1095 {
1096 	int ret;
1097 
1098 	DRM_INFO("[DRM-DRV]%s start\n\n", __func__);
1099 /*register sunxi-de driver*/
1100 	ret = sunxi_de_module_init();
1101 	if (ret < 0) {
1102 		DRM_ERROR("sunxi_de_module_init failed!\n");
1103 		goto de_err;
1104 	}
1105 
1106 /*register sunxi-tcon driver*/
1107 	ret = sunxi_tcon_module_init();
1108 	if (ret < 0) {
1109 		DRM_ERROR("sunxi_tcon_module_init failed!\n");
1110 		goto tcon_err;
1111 	}
1112 /*register sunxi-lcd driver*/
1113 #ifdef CONFIG_AW_DRM_LCD
1114 	ret = sunxi_lcd_module_init();
1115 	if (ret < 0) {
1116 		sunxi_lcd_module_exit();
1117 		DRM_ERROR("sunxi_lcd_module_init failed!\n");
1118 		goto drm_err;
1119 	}
1120 #endif
1121 
1122 #ifdef CONFIG_AW_DRM_TV
1123 	ret = sunxi_tv_module_init();
1124 	if (ret < 0) {
1125 		DRM_ERROR("sunxi_tv_module_init failed!\n");
1126 		sunxi_tv_module_exit();
1127 		goto drm_err;
1128 	}
1129 #endif
1130 
1131 #if defined(CONFIG_AW_DRM_HDMI14)
1132 	ret = sunxi_hdmi_module_init();
1133 	if (ret < 0) {
1134 		DRM_ERROR("sunxi_hdmi_module_init failed!\n");
1135 		sunxi_hdmi_module_exit();
1136 		goto drm_err;
1137 	}
1138 #elif defined(CONFIG_AW_DRM_HDMI20)
1139 	ret = sunxi_hdmi20_module_init();
1140 	if (ret < 0) {
1141 		DRM_ERROR("sunxi_hdmi_module_init failed!\n");
1142 		sunxi_hdmi20_module_exit();
1143 		goto drm_err;
1144 	}
1145 #endif
1146 
1147 /*register sunxi-drm driver*/
1148 	ret = platform_driver_register(&sunxi_drm_platform_driver);
1149 	if (ret < 0) {
1150 		DRM_ERROR("drm platform_driver_register failed!\n");
1151 		goto drm_err;
1152 	}
1153 
1154 	/*if (sunxi_drv_prv.drm_dev) {
1155 		if (sunxi_drm_sysfs_init(sunxi_drv_prv.drm_dev) < 0) {
1156 			DRM_ERROR("sunxi_drm_sysfs_init failed\n");
1157 			goto drm_err;
1158 		}
1159 	}*/
1160 
1161 	DRM_INFO("[DRM-DRV]%s end\n\n", __func__);
1162 	return 0;
1163 
1164 drm_err:
1165 	platform_driver_unregister(&sunxi_drm_platform_driver);
1166 
1167 tcon_err:
1168 	sunxi_tcon_module_exit();
1169 de_err:
1170 	sunxi_de_module_exit();
1171 	DRM_INFO("[DRM-DRV]%s failed\n", __func__);
1172 	return -1;
1173 }
1174 
sunxi_drm_drv_exit(void)1175 static void __exit sunxi_drm_drv_exit(void)
1176 {
1177 	DRM_INFO("[DRM-DRV]%s start\n", __func__);
1178 
1179 	//sunxi_drm_sysfs_exit(sunxi_drv_prv.drm_dev);
1180 	platform_driver_unregister(&sunxi_drm_platform_driver);
1181 #ifdef CONFIG_AW_DRM_LCD
1182 	sunxi_lcd_module_exit();
1183 #endif
1184 
1185 #ifdef CONFIG_AW_DRM_TV
1186 	sunxi_tv_module_exit();
1187 #endif
1188 
1189 #if defined(CONFIG_AW_DRM_HDMI14)
1190 	sunxi_hdmi_module_exit();
1191 #elif defined(CONFIG_AW_DRM_HDMI20)
1192 	sunxi_hdmi20_module_exit();
1193 #endif
1194 	sunxi_tcon_module_exit();
1195 	sunxi_de_module_exit();
1196 }
1197 
1198 module_init(sunxi_drm_drv_init);
1199 module_exit(sunxi_drm_drv_exit);
1200 MODULE_AUTHOR("zhengwanyu");
1201 MODULE_AUTHOR("hongyaobin");
1202 
1203 MODULE_DESCRIPTION("Allwinnertech SoC DRM Driver");
1204 MODULE_LICENSE("GPL");
1205