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