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