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