xref: /linux/drivers/gpu/drm/tiny/simpledrm.c (revision cbdb1f163af2bb90d01be1f0263df1d8d5c9d9d3)
1 // SPDX-License-Identifier: GPL-2.0-only
2 
3 #include <linux/clk.h>
4 #include <linux/of_clk.h>
5 #include <linux/minmax.h>
6 #include <linux/platform_data/simplefb.h>
7 #include <linux/platform_device.h>
8 #include <linux/regulator/consumer.h>
9 
10 #include <drm/drm_aperture.h>
11 #include <drm/drm_atomic.h>
12 #include <drm/drm_atomic_state_helper.h>
13 #include <drm/drm_connector.h>
14 #include <drm/drm_crtc_helper.h>
15 #include <drm/drm_damage_helper.h>
16 #include <drm/drm_device.h>
17 #include <drm/drm_drv.h>
18 #include <drm/drm_fbdev_generic.h>
19 #include <drm/drm_format_helper.h>
20 #include <drm/drm_gem_atomic_helper.h>
21 #include <drm/drm_gem_framebuffer_helper.h>
22 #include <drm/drm_gem_shmem_helper.h>
23 #include <drm/drm_managed.h>
24 #include <drm/drm_modeset_helper_vtables.h>
25 #include <drm/drm_plane_helper.h>
26 #include <drm/drm_probe_helper.h>
27 
28 #define DRIVER_NAME	"simpledrm"
29 #define DRIVER_DESC	"DRM driver for simple-framebuffer platform devices"
30 #define DRIVER_DATE	"20200625"
31 #define DRIVER_MAJOR	1
32 #define DRIVER_MINOR	0
33 
34 /*
35  * Helpers for simplefb
36  */
37 
38 static int
39 simplefb_get_validated_int(struct drm_device *dev, const char *name,
40 			   uint32_t value)
41 {
42 	if (value > INT_MAX) {
43 		drm_err(dev, "simplefb: invalid framebuffer %s of %u\n",
44 			name, value);
45 		return -EINVAL;
46 	}
47 	return (int)value;
48 }
49 
50 static int
51 simplefb_get_validated_int0(struct drm_device *dev, const char *name,
52 			    uint32_t value)
53 {
54 	if (!value) {
55 		drm_err(dev, "simplefb: invalid framebuffer %s of %u\n",
56 			name, value);
57 		return -EINVAL;
58 	}
59 	return simplefb_get_validated_int(dev, name, value);
60 }
61 
62 static const struct drm_format_info *
63 simplefb_get_validated_format(struct drm_device *dev, const char *format_name)
64 {
65 	static const struct simplefb_format formats[] = SIMPLEFB_FORMATS;
66 	const struct simplefb_format *fmt = formats;
67 	const struct simplefb_format *end = fmt + ARRAY_SIZE(formats);
68 	const struct drm_format_info *info;
69 
70 	if (!format_name) {
71 		drm_err(dev, "simplefb: missing framebuffer format\n");
72 		return ERR_PTR(-EINVAL);
73 	}
74 
75 	while (fmt < end) {
76 		if (!strcmp(format_name, fmt->name)) {
77 			info = drm_format_info(fmt->fourcc);
78 			if (!info)
79 				return ERR_PTR(-EINVAL);
80 			return info;
81 		}
82 		++fmt;
83 	}
84 
85 	drm_err(dev, "simplefb: unknown framebuffer format %s\n",
86 		format_name);
87 
88 	return ERR_PTR(-EINVAL);
89 }
90 
91 static int
92 simplefb_get_width_pd(struct drm_device *dev,
93 		      const struct simplefb_platform_data *pd)
94 {
95 	return simplefb_get_validated_int0(dev, "width", pd->width);
96 }
97 
98 static int
99 simplefb_get_height_pd(struct drm_device *dev,
100 		       const struct simplefb_platform_data *pd)
101 {
102 	return simplefb_get_validated_int0(dev, "height", pd->height);
103 }
104 
105 static int
106 simplefb_get_stride_pd(struct drm_device *dev,
107 		       const struct simplefb_platform_data *pd)
108 {
109 	return simplefb_get_validated_int(dev, "stride", pd->stride);
110 }
111 
112 static const struct drm_format_info *
113 simplefb_get_format_pd(struct drm_device *dev,
114 		       const struct simplefb_platform_data *pd)
115 {
116 	return simplefb_get_validated_format(dev, pd->format);
117 }
118 
119 static int
120 simplefb_read_u32_of(struct drm_device *dev, struct device_node *of_node,
121 		     const char *name, u32 *value)
122 {
123 	int ret = of_property_read_u32(of_node, name, value);
124 
125 	if (ret)
126 		drm_err(dev, "simplefb: cannot parse framebuffer %s: error %d\n",
127 			name, ret);
128 	return ret;
129 }
130 
131 static int
132 simplefb_read_string_of(struct drm_device *dev, struct device_node *of_node,
133 			const char *name, const char **value)
134 {
135 	int ret = of_property_read_string(of_node, name, value);
136 
137 	if (ret)
138 		drm_err(dev, "simplefb: cannot parse framebuffer %s: error %d\n",
139 			name, ret);
140 	return ret;
141 }
142 
143 static int
144 simplefb_get_width_of(struct drm_device *dev, struct device_node *of_node)
145 {
146 	u32 width;
147 	int ret = simplefb_read_u32_of(dev, of_node, "width", &width);
148 
149 	if (ret)
150 		return ret;
151 	return simplefb_get_validated_int0(dev, "width", width);
152 }
153 
154 static int
155 simplefb_get_height_of(struct drm_device *dev, struct device_node *of_node)
156 {
157 	u32 height;
158 	int ret = simplefb_read_u32_of(dev, of_node, "height", &height);
159 
160 	if (ret)
161 		return ret;
162 	return simplefb_get_validated_int0(dev, "height", height);
163 }
164 
165 static int
166 simplefb_get_stride_of(struct drm_device *dev, struct device_node *of_node)
167 {
168 	u32 stride;
169 	int ret = simplefb_read_u32_of(dev, of_node, "stride", &stride);
170 
171 	if (ret)
172 		return ret;
173 	return simplefb_get_validated_int(dev, "stride", stride);
174 }
175 
176 static const struct drm_format_info *
177 simplefb_get_format_of(struct drm_device *dev, struct device_node *of_node)
178 {
179 	const char *format;
180 	int ret = simplefb_read_string_of(dev, of_node, "format", &format);
181 
182 	if (ret)
183 		return ERR_PTR(ret);
184 	return simplefb_get_validated_format(dev, format);
185 }
186 
187 /*
188  * Simple Framebuffer device
189  */
190 
191 struct simpledrm_device {
192 	struct drm_device dev;
193 
194 	/* clocks */
195 #if defined CONFIG_OF && defined CONFIG_COMMON_CLK
196 	unsigned int clk_count;
197 	struct clk **clks;
198 #endif
199 	/* regulators */
200 #if defined CONFIG_OF && defined CONFIG_REGULATOR
201 	unsigned int regulator_count;
202 	struct regulator **regulators;
203 #endif
204 
205 	/* simplefb settings */
206 	struct drm_display_mode mode;
207 	const struct drm_format_info *format;
208 	unsigned int pitch;
209 
210 	/* memory management */
211 	void __iomem *screen_base;
212 
213 	/* modesetting */
214 	uint32_t formats[8];
215 	size_t nformats;
216 	struct drm_plane primary_plane;
217 	struct drm_crtc crtc;
218 	struct drm_encoder encoder;
219 	struct drm_connector connector;
220 };
221 
222 static struct simpledrm_device *simpledrm_device_of_dev(struct drm_device *dev)
223 {
224 	return container_of(dev, struct simpledrm_device, dev);
225 }
226 
227 /*
228  * Hardware
229  */
230 
231 #if defined CONFIG_OF && defined CONFIG_COMMON_CLK
232 /*
233  * Clock handling code.
234  *
235  * Here we handle the clocks property of our "simple-framebuffer" dt node.
236  * This is necessary so that we can make sure that any clocks needed by
237  * the display engine that the bootloader set up for us (and for which it
238  * provided a simplefb dt node), stay up, for the life of the simplefb
239  * driver.
240  *
241  * When the driver unloads, we cleanly disable, and then release the clocks.
242  *
243  * We only complain about errors here, no action is taken as the most likely
244  * error can only happen due to a mismatch between the bootloader which set
245  * up simplefb, and the clock definitions in the device tree. Chances are
246  * that there are no adverse effects, and if there are, a clean teardown of
247  * the fb probe will not help us much either. So just complain and carry on,
248  * and hope that the user actually gets a working fb at the end of things.
249  */
250 
251 static void simpledrm_device_release_clocks(void *res)
252 {
253 	struct simpledrm_device *sdev = simpledrm_device_of_dev(res);
254 	unsigned int i;
255 
256 	for (i = 0; i < sdev->clk_count; ++i) {
257 		if (sdev->clks[i]) {
258 			clk_disable_unprepare(sdev->clks[i]);
259 			clk_put(sdev->clks[i]);
260 		}
261 	}
262 }
263 
264 static int simpledrm_device_init_clocks(struct simpledrm_device *sdev)
265 {
266 	struct drm_device *dev = &sdev->dev;
267 	struct platform_device *pdev = to_platform_device(dev->dev);
268 	struct device_node *of_node = pdev->dev.of_node;
269 	struct clk *clock;
270 	unsigned int i;
271 	int ret;
272 
273 	if (dev_get_platdata(&pdev->dev) || !of_node)
274 		return 0;
275 
276 	sdev->clk_count = of_clk_get_parent_count(of_node);
277 	if (!sdev->clk_count)
278 		return 0;
279 
280 	sdev->clks = drmm_kzalloc(dev, sdev->clk_count * sizeof(sdev->clks[0]),
281 				  GFP_KERNEL);
282 	if (!sdev->clks)
283 		return -ENOMEM;
284 
285 	for (i = 0; i < sdev->clk_count; ++i) {
286 		clock = of_clk_get(of_node, i);
287 		if (IS_ERR(clock)) {
288 			ret = PTR_ERR(clock);
289 			if (ret == -EPROBE_DEFER)
290 				goto err;
291 			drm_err(dev, "clock %u not found: %d\n", i, ret);
292 			continue;
293 		}
294 		ret = clk_prepare_enable(clock);
295 		if (ret) {
296 			drm_err(dev, "failed to enable clock %u: %d\n",
297 				i, ret);
298 			clk_put(clock);
299 			continue;
300 		}
301 		sdev->clks[i] = clock;
302 	}
303 
304 	return devm_add_action_or_reset(&pdev->dev,
305 					simpledrm_device_release_clocks,
306 					sdev);
307 
308 err:
309 	while (i) {
310 		--i;
311 		if (sdev->clks[i]) {
312 			clk_disable_unprepare(sdev->clks[i]);
313 			clk_put(sdev->clks[i]);
314 		}
315 	}
316 	return ret;
317 }
318 #else
319 static int simpledrm_device_init_clocks(struct simpledrm_device *sdev)
320 {
321 	return 0;
322 }
323 #endif
324 
325 #if defined CONFIG_OF && defined CONFIG_REGULATOR
326 
327 #define SUPPLY_SUFFIX "-supply"
328 
329 /*
330  * Regulator handling code.
331  *
332  * Here we handle the num-supplies and vin*-supply properties of our
333  * "simple-framebuffer" dt node. This is necessary so that we can make sure
334  * that any regulators needed by the display hardware that the bootloader
335  * set up for us (and for which it provided a simplefb dt node), stay up,
336  * for the life of the simplefb driver.
337  *
338  * When the driver unloads, we cleanly disable, and then release the
339  * regulators.
340  *
341  * We only complain about errors here, no action is taken as the most likely
342  * error can only happen due to a mismatch between the bootloader which set
343  * up simplefb, and the regulator definitions in the device tree. Chances are
344  * that there are no adverse effects, and if there are, a clean teardown of
345  * the fb probe will not help us much either. So just complain and carry on,
346  * and hope that the user actually gets a working fb at the end of things.
347  */
348 
349 static void simpledrm_device_release_regulators(void *res)
350 {
351 	struct simpledrm_device *sdev = simpledrm_device_of_dev(res);
352 	unsigned int i;
353 
354 	for (i = 0; i < sdev->regulator_count; ++i) {
355 		if (sdev->regulators[i]) {
356 			regulator_disable(sdev->regulators[i]);
357 			regulator_put(sdev->regulators[i]);
358 		}
359 	}
360 }
361 
362 static int simpledrm_device_init_regulators(struct simpledrm_device *sdev)
363 {
364 	struct drm_device *dev = &sdev->dev;
365 	struct platform_device *pdev = to_platform_device(dev->dev);
366 	struct device_node *of_node = pdev->dev.of_node;
367 	struct property *prop;
368 	struct regulator *regulator;
369 	const char *p;
370 	unsigned int count = 0, i = 0;
371 	int ret;
372 
373 	if (dev_get_platdata(&pdev->dev) || !of_node)
374 		return 0;
375 
376 	/* Count the number of regulator supplies */
377 	for_each_property_of_node(of_node, prop) {
378 		p = strstr(prop->name, SUPPLY_SUFFIX);
379 		if (p && p != prop->name)
380 			++count;
381 	}
382 
383 	if (!count)
384 		return 0;
385 
386 	sdev->regulators = drmm_kzalloc(dev,
387 					count * sizeof(sdev->regulators[0]),
388 					GFP_KERNEL);
389 	if (!sdev->regulators)
390 		return -ENOMEM;
391 
392 	for_each_property_of_node(of_node, prop) {
393 		char name[32]; /* 32 is max size of property name */
394 		size_t len;
395 
396 		p = strstr(prop->name, SUPPLY_SUFFIX);
397 		if (!p || p == prop->name)
398 			continue;
399 		len = strlen(prop->name) - strlen(SUPPLY_SUFFIX) + 1;
400 		strscpy(name, prop->name, min(sizeof(name), len));
401 
402 		regulator = regulator_get_optional(&pdev->dev, name);
403 		if (IS_ERR(regulator)) {
404 			ret = PTR_ERR(regulator);
405 			if (ret == -EPROBE_DEFER)
406 				goto err;
407 			drm_err(dev, "regulator %s not found: %d\n",
408 				name, ret);
409 			continue;
410 		}
411 
412 		ret = regulator_enable(regulator);
413 		if (ret) {
414 			drm_err(dev, "failed to enable regulator %u: %d\n",
415 				i, ret);
416 			regulator_put(regulator);
417 			continue;
418 		}
419 
420 		sdev->regulators[i++] = regulator;
421 	}
422 	sdev->regulator_count = i;
423 
424 	return devm_add_action_or_reset(&pdev->dev,
425 					simpledrm_device_release_regulators,
426 					sdev);
427 
428 err:
429 	while (i) {
430 		--i;
431 		if (sdev->regulators[i]) {
432 			regulator_disable(sdev->regulators[i]);
433 			regulator_put(sdev->regulators[i]);
434 		}
435 	}
436 	return ret;
437 }
438 #else
439 static int simpledrm_device_init_regulators(struct simpledrm_device *sdev)
440 {
441 	return 0;
442 }
443 #endif
444 
445 /*
446  * Modesetting
447  */
448 
449 /*
450  * Support all formats of simplefb and maybe more; in order
451  * of preference. The display's update function will do any
452  * conversion necessary.
453  *
454  * TODO: Add blit helpers for remaining formats and uncomment
455  *       constants.
456  */
457 static const uint32_t simpledrm_primary_plane_formats[] = {
458 	DRM_FORMAT_XRGB8888,
459 	DRM_FORMAT_ARGB8888,
460 	DRM_FORMAT_RGB565,
461 	//DRM_FORMAT_XRGB1555,
462 	//DRM_FORMAT_ARGB1555,
463 	DRM_FORMAT_RGB888,
464 	DRM_FORMAT_XRGB2101010,
465 	DRM_FORMAT_ARGB2101010,
466 };
467 
468 static const uint64_t simpledrm_primary_plane_format_modifiers[] = {
469 	DRM_FORMAT_MOD_LINEAR,
470 	DRM_FORMAT_MOD_INVALID
471 };
472 
473 static void simpledrm_primary_plane_helper_atomic_update(struct drm_plane *plane,
474 							 struct drm_atomic_state *state)
475 {
476 	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
477 	struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
478 	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
479 	struct drm_framebuffer *fb = plane_state->fb;
480 	struct drm_device *dev = plane->dev;
481 	struct simpledrm_device *sdev = simpledrm_device_of_dev(dev);
482 	struct drm_atomic_helper_damage_iter iter;
483 	struct drm_rect damage;
484 	int ret, idx;
485 
486 	ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
487 	if (ret)
488 		return;
489 
490 	if (!drm_dev_enter(dev, &idx))
491 		goto out_drm_gem_fb_end_cpu_access;
492 
493 	drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
494 	drm_atomic_for_each_plane_damage(&iter, &damage) {
495 		struct iosys_map dst = IOSYS_MAP_INIT_VADDR(sdev->screen_base);
496 		struct drm_rect dst_clip = plane_state->dst;
497 
498 		if (!drm_rect_intersect(&dst_clip, &damage))
499 			continue;
500 
501 		iosys_map_incr(&dst, drm_fb_clip_offset(sdev->pitch, sdev->format, &dst_clip));
502 		drm_fb_blit(&dst, &sdev->pitch, sdev->format->format, shadow_plane_state->data, fb,
503 			    &damage);
504 	}
505 
506 	drm_dev_exit(idx);
507 out_drm_gem_fb_end_cpu_access:
508 	drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
509 }
510 
511 static void simpledrm_primary_plane_helper_atomic_disable(struct drm_plane *plane,
512 							  struct drm_atomic_state *state)
513 {
514 	struct drm_device *dev = plane->dev;
515 	struct simpledrm_device *sdev = simpledrm_device_of_dev(dev);
516 	int idx;
517 
518 	if (!drm_dev_enter(dev, &idx))
519 		return;
520 
521 	/* Clear screen to black if disabled */
522 	memset_io(sdev->screen_base, 0, sdev->pitch * sdev->mode.vdisplay);
523 
524 	drm_dev_exit(idx);
525 }
526 
527 static const struct drm_plane_helper_funcs simpledrm_primary_plane_helper_funcs = {
528 	DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
529 	.atomic_check = drm_plane_helper_atomic_check,
530 	.atomic_update = simpledrm_primary_plane_helper_atomic_update,
531 	.atomic_disable = simpledrm_primary_plane_helper_atomic_disable,
532 };
533 
534 static const struct drm_plane_funcs simpledrm_primary_plane_funcs = {
535 	.update_plane = drm_atomic_helper_update_plane,
536 	.disable_plane = drm_atomic_helper_disable_plane,
537 	.destroy = drm_plane_cleanup,
538 	DRM_GEM_SHADOW_PLANE_FUNCS,
539 };
540 
541 static enum drm_mode_status simpledrm_crtc_helper_mode_valid(struct drm_crtc *crtc,
542 							     const struct drm_display_mode *mode)
543 {
544 	struct simpledrm_device *sdev = simpledrm_device_of_dev(crtc->dev);
545 
546 	return drm_crtc_helper_mode_valid_fixed(crtc, mode, &sdev->mode);
547 }
548 
549 /*
550  * The CRTC is always enabled. Screen updates are performed by
551  * the primary plane's atomic_update function. Disabling clears
552  * the screen in the primary plane's atomic_disable function.
553  */
554 static const struct drm_crtc_helper_funcs simpledrm_crtc_helper_funcs = {
555 	.mode_valid = simpledrm_crtc_helper_mode_valid,
556 	.atomic_check = drm_crtc_helper_atomic_check,
557 };
558 
559 static const struct drm_crtc_funcs simpledrm_crtc_funcs = {
560 	.reset = drm_atomic_helper_crtc_reset,
561 	.destroy = drm_crtc_cleanup,
562 	.set_config = drm_atomic_helper_set_config,
563 	.page_flip = drm_atomic_helper_page_flip,
564 	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
565 	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
566 };
567 
568 static const struct drm_encoder_funcs simpledrm_encoder_funcs = {
569 	.destroy = drm_encoder_cleanup,
570 };
571 
572 static int simpledrm_connector_helper_get_modes(struct drm_connector *connector)
573 {
574 	struct simpledrm_device *sdev = simpledrm_device_of_dev(connector->dev);
575 
576 	return drm_connector_helper_get_modes_fixed(connector, &sdev->mode);
577 }
578 
579 static const struct drm_connector_helper_funcs simpledrm_connector_helper_funcs = {
580 	.get_modes = simpledrm_connector_helper_get_modes,
581 };
582 
583 static const struct drm_connector_funcs simpledrm_connector_funcs = {
584 	.reset = drm_atomic_helper_connector_reset,
585 	.fill_modes = drm_helper_probe_single_connector_modes,
586 	.destroy = drm_connector_cleanup,
587 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
588 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
589 };
590 
591 static const struct drm_mode_config_funcs simpledrm_mode_config_funcs = {
592 	.fb_create = drm_gem_fb_create_with_dirty,
593 	.atomic_check = drm_atomic_helper_check,
594 	.atomic_commit = drm_atomic_helper_commit,
595 };
596 
597 /*
598  * Init / Cleanup
599  */
600 
601 static struct drm_display_mode simpledrm_mode(unsigned int width,
602 					      unsigned int height)
603 {
604 	/*
605 	 * Assume a monitor resolution of 96 dpi to
606 	 * get a somewhat reasonable screen size.
607 	 */
608 	const struct drm_display_mode mode = {
609 		DRM_MODE_INIT(60, width, height,
610 			      DRM_MODE_RES_MM(width, 96ul),
611 			      DRM_MODE_RES_MM(height, 96ul))
612 	};
613 
614 	return mode;
615 }
616 
617 static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv,
618 							struct platform_device *pdev)
619 {
620 	const struct simplefb_platform_data *pd = dev_get_platdata(&pdev->dev);
621 	struct device_node *of_node = pdev->dev.of_node;
622 	struct simpledrm_device *sdev;
623 	struct drm_device *dev;
624 	int width, height, stride;
625 	const struct drm_format_info *format;
626 	struct resource *res, *mem;
627 	void __iomem *screen_base;
628 	struct drm_plane *primary_plane;
629 	struct drm_crtc *crtc;
630 	struct drm_encoder *encoder;
631 	struct drm_connector *connector;
632 	unsigned long max_width, max_height;
633 	size_t nformats;
634 	int ret;
635 
636 	sdev = devm_drm_dev_alloc(&pdev->dev, drv, struct simpledrm_device, dev);
637 	if (IS_ERR(sdev))
638 		return ERR_CAST(sdev);
639 	dev = &sdev->dev;
640 	platform_set_drvdata(pdev, sdev);
641 
642 	/*
643 	 * Hardware settings
644 	 */
645 
646 	ret = simpledrm_device_init_clocks(sdev);
647 	if (ret)
648 		return ERR_PTR(ret);
649 	ret = simpledrm_device_init_regulators(sdev);
650 	if (ret)
651 		return ERR_PTR(ret);
652 
653 	if (pd) {
654 		width = simplefb_get_width_pd(dev, pd);
655 		if (width < 0)
656 			return ERR_PTR(width);
657 		height = simplefb_get_height_pd(dev, pd);
658 		if (height < 0)
659 			return ERR_PTR(height);
660 		stride = simplefb_get_stride_pd(dev, pd);
661 		if (stride < 0)
662 			return ERR_PTR(stride);
663 		format = simplefb_get_format_pd(dev, pd);
664 		if (IS_ERR(format))
665 			return ERR_CAST(format);
666 	} else if (of_node) {
667 		width = simplefb_get_width_of(dev, of_node);
668 		if (width < 0)
669 			return ERR_PTR(width);
670 		height = simplefb_get_height_of(dev, of_node);
671 		if (height < 0)
672 			return ERR_PTR(height);
673 		stride = simplefb_get_stride_of(dev, of_node);
674 		if (stride < 0)
675 			return ERR_PTR(stride);
676 		format = simplefb_get_format_of(dev, of_node);
677 		if (IS_ERR(format))
678 			return ERR_CAST(format);
679 	} else {
680 		drm_err(dev, "no simplefb configuration found\n");
681 		return ERR_PTR(-ENODEV);
682 	}
683 	if (!stride) {
684 		stride = drm_format_info_min_pitch(format, 0, width);
685 		if (drm_WARN_ON(dev, !stride))
686 			return ERR_PTR(-EINVAL);
687 	}
688 
689 	sdev->mode = simpledrm_mode(width, height);
690 	sdev->format = format;
691 	sdev->pitch = stride;
692 
693 	drm_dbg(dev, "display mode={" DRM_MODE_FMT "}\n", DRM_MODE_ARG(&sdev->mode));
694 	drm_dbg(dev, "framebuffer format=%p4cc, size=%dx%d, stride=%d byte\n",
695 		&format->format, width, height, stride);
696 
697 	/*
698 	 * Memory management
699 	 */
700 
701 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
702 	if (!res)
703 		return ERR_PTR(-EINVAL);
704 
705 	ret = devm_aperture_acquire_from_firmware(dev, res->start, resource_size(res));
706 	if (ret) {
707 		drm_err(dev, "could not acquire memory range %pr: error %d\n", res, ret);
708 		return ERR_PTR(ret);
709 	}
710 
711 	mem = devm_request_mem_region(&pdev->dev, res->start, resource_size(res), drv->name);
712 	if (!mem) {
713 		/*
714 		 * We cannot make this fatal. Sometimes this comes from magic
715 		 * spaces our resource handlers simply don't know about. Use
716 		 * the I/O-memory resource as-is and try to map that instead.
717 		 */
718 		drm_warn(dev, "could not acquire memory region %pr\n", res);
719 		mem = res;
720 	}
721 
722 	screen_base = devm_ioremap_wc(&pdev->dev, mem->start, resource_size(mem));
723 	if (!screen_base)
724 		return ERR_PTR(-ENOMEM);
725 	sdev->screen_base = screen_base;
726 
727 	/*
728 	 * Modesetting
729 	 */
730 
731 	ret = drmm_mode_config_init(dev);
732 	if (ret)
733 		return ERR_PTR(ret);
734 
735 	max_width = max_t(unsigned long, width, DRM_SHADOW_PLANE_MAX_WIDTH);
736 	max_height = max_t(unsigned long, height, DRM_SHADOW_PLANE_MAX_HEIGHT);
737 
738 	dev->mode_config.min_width = width;
739 	dev->mode_config.max_width = max_width;
740 	dev->mode_config.min_height = height;
741 	dev->mode_config.max_height = max_height;
742 	dev->mode_config.preferred_depth = format->cpp[0] * 8;
743 	dev->mode_config.funcs = &simpledrm_mode_config_funcs;
744 
745 	/* Primary plane */
746 
747 	nformats = drm_fb_build_fourcc_list(dev, &format->format, 1,
748 					    simpledrm_primary_plane_formats,
749 					    ARRAY_SIZE(simpledrm_primary_plane_formats),
750 					    sdev->formats, ARRAY_SIZE(sdev->formats));
751 
752 	primary_plane = &sdev->primary_plane;
753 	ret = drm_universal_plane_init(dev, primary_plane, 0, &simpledrm_primary_plane_funcs,
754 				       sdev->formats, nformats,
755 				       simpledrm_primary_plane_format_modifiers,
756 				       DRM_PLANE_TYPE_PRIMARY, NULL);
757 	if (ret)
758 		return ERR_PTR(ret);
759 	drm_plane_helper_add(primary_plane, &simpledrm_primary_plane_helper_funcs);
760 	drm_plane_enable_fb_damage_clips(primary_plane);
761 
762 	/* CRTC */
763 
764 	crtc = &sdev->crtc;
765 	ret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL,
766 					&simpledrm_crtc_funcs, NULL);
767 	if (ret)
768 		return ERR_PTR(ret);
769 	drm_crtc_helper_add(crtc, &simpledrm_crtc_helper_funcs);
770 
771 	/* Encoder */
772 
773 	encoder = &sdev->encoder;
774 	ret = drm_encoder_init(dev, encoder, &simpledrm_encoder_funcs,
775 			       DRM_MODE_ENCODER_NONE, NULL);
776 	if (ret)
777 		return ERR_PTR(ret);
778 	encoder->possible_crtcs = drm_crtc_mask(crtc);
779 
780 	/* Connector */
781 
782 	connector = &sdev->connector;
783 	ret = drm_connector_init(dev, connector, &simpledrm_connector_funcs,
784 				 DRM_MODE_CONNECTOR_Unknown);
785 	if (ret)
786 		return ERR_PTR(ret);
787 	drm_connector_helper_add(connector, &simpledrm_connector_helper_funcs);
788 	drm_connector_set_panel_orientation_with_quirk(connector,
789 						       DRM_MODE_PANEL_ORIENTATION_UNKNOWN,
790 						       width, height);
791 
792 	ret = drm_connector_attach_encoder(connector, encoder);
793 	if (ret)
794 		return ERR_PTR(ret);
795 
796 	drm_mode_config_reset(dev);
797 
798 	return sdev;
799 }
800 
801 /*
802  * DRM driver
803  */
804 
805 DEFINE_DRM_GEM_FOPS(simpledrm_fops);
806 
807 static struct drm_driver simpledrm_driver = {
808 	DRM_GEM_SHMEM_DRIVER_OPS,
809 	.name			= DRIVER_NAME,
810 	.desc			= DRIVER_DESC,
811 	.date			= DRIVER_DATE,
812 	.major			= DRIVER_MAJOR,
813 	.minor			= DRIVER_MINOR,
814 	.driver_features	= DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
815 	.fops			= &simpledrm_fops,
816 };
817 
818 /*
819  * Platform driver
820  */
821 
822 static int simpledrm_probe(struct platform_device *pdev)
823 {
824 	struct simpledrm_device *sdev;
825 	struct drm_device *dev;
826 	int ret;
827 
828 	sdev = simpledrm_device_create(&simpledrm_driver, pdev);
829 	if (IS_ERR(sdev))
830 		return PTR_ERR(sdev);
831 	dev = &sdev->dev;
832 
833 	ret = drm_dev_register(dev, 0);
834 	if (ret)
835 		return ret;
836 
837 	drm_fbdev_generic_setup(dev, 0);
838 
839 	return 0;
840 }
841 
842 static int simpledrm_remove(struct platform_device *pdev)
843 {
844 	struct simpledrm_device *sdev = platform_get_drvdata(pdev);
845 	struct drm_device *dev = &sdev->dev;
846 
847 	drm_dev_unplug(dev);
848 
849 	return 0;
850 }
851 
852 static const struct of_device_id simpledrm_of_match_table[] = {
853 	{ .compatible = "simple-framebuffer", },
854 	{ },
855 };
856 MODULE_DEVICE_TABLE(of, simpledrm_of_match_table);
857 
858 static struct platform_driver simpledrm_platform_driver = {
859 	.driver = {
860 		.name = "simple-framebuffer", /* connect to sysfb */
861 		.of_match_table = simpledrm_of_match_table,
862 	},
863 	.probe = simpledrm_probe,
864 	.remove = simpledrm_remove,
865 };
866 
867 module_platform_driver(simpledrm_platform_driver);
868 
869 MODULE_DESCRIPTION(DRIVER_DESC);
870 MODULE_LICENSE("GPL v2");
871