projects/linux·blob master · refs

972 lines · 25.5 KiB

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