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