4f605c5fe8562292569779da776410e6b432666d
[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_format_name_buf buf;
472         struct drm_device *dev = &sdev->dev;
473         struct platform_device *pdev = sdev->pdev;
474         const struct simplefb_platform_data *pd = dev_get_platdata(&pdev->dev);
475         struct device_node *of_node = pdev->dev.of_node;
476
477         if (pd) {
478                 width = simplefb_get_width_pd(dev, pd);
479                 if (width < 0)
480                         return width;
481                 height = simplefb_get_height_pd(dev, pd);
482                 if (height < 0)
483                         return height;
484                 stride = simplefb_get_stride_pd(dev, pd);
485                 if (stride < 0)
486                         return stride;
487                 format = simplefb_get_format_pd(dev, pd);
488                 if (IS_ERR(format))
489                         return PTR_ERR(format);
490         } else if (of_node) {
491                 width = simplefb_get_width_of(dev, of_node);
492                 if (width < 0)
493                         return width;
494                 height = simplefb_get_height_of(dev, of_node);
495                 if (height < 0)
496                         return height;
497                 stride = simplefb_get_stride_of(dev, of_node);
498                 if (stride < 0)
499                         return stride;
500                 format = simplefb_get_format_of(dev, of_node);
501                 if (IS_ERR(format))
502                         return PTR_ERR(format);
503         } else {
504                 drm_err(dev, "no simplefb configuration found\n");
505                 return -ENODEV;
506         }
507
508         sdev->mode = simpledrm_mode(width, height);
509         sdev->format = format;
510         sdev->pitch = stride;
511
512         drm_dbg_kms(dev, "display mode={" DRM_MODE_FMT "}\n",
513                     DRM_MODE_ARG(&sdev->mode));
514         drm_dbg_kms(dev,
515                     "framebuffer format=\"%s\", size=%dx%d, stride=%d byte\n",
516                     drm_get_format_name(format->format, &buf), width,
517                     height, stride);
518
519         return 0;
520 }
521
522 /*
523  * Memory management
524  */
525
526 static int simpledrm_device_init_mm(struct simpledrm_device *sdev)
527 {
528         struct drm_device *dev = &sdev->dev;
529         struct platform_device *pdev = sdev->pdev;
530         struct resource *mem;
531         void __iomem *screen_base;
532         int ret;
533
534         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
535         if (!mem)
536                 return -EINVAL;
537
538         ret = devm_aperture_acquire_from_firmware(dev, mem->start, resource_size(mem));
539         if (ret) {
540                 drm_err(dev, "could not acquire memory range %pr: error %d\n",
541                         mem, ret);
542                 return ret;
543         }
544
545         screen_base = devm_ioremap_wc(&pdev->dev, mem->start,
546                                       resource_size(mem));
547         if (!screen_base)
548                 return -ENOMEM;
549
550         sdev->mem = mem;
551         sdev->screen_base = screen_base;
552
553         return 0;
554 }
555
556 /*
557  * Modesetting
558  */
559
560 /*
561  * Support all formats of simplefb and maybe more; in order
562  * of preference. The display's update function will do any
563  * conversion necessary.
564  *
565  * TODO: Add blit helpers for remaining formats and uncomment
566  *       constants.
567  */
568 static const uint32_t simpledrm_default_formats[] = {
569         DRM_FORMAT_XRGB8888,
570         DRM_FORMAT_ARGB8888,
571         DRM_FORMAT_RGB565,
572         //DRM_FORMAT_XRGB1555,
573         //DRM_FORMAT_ARGB1555,
574         DRM_FORMAT_RGB888,
575         //DRM_FORMAT_XRGB2101010,
576         //DRM_FORMAT_ARGB2101010,
577 };
578
579 static const uint64_t simpledrm_format_modifiers[] = {
580         DRM_FORMAT_MOD_LINEAR,
581         DRM_FORMAT_MOD_INVALID
582 };
583
584 static int simpledrm_connector_helper_get_modes(struct drm_connector *connector)
585 {
586         struct simpledrm_device *sdev = simpledrm_device_of_dev(connector->dev);
587         struct drm_display_mode *mode;
588
589         mode = drm_mode_duplicate(connector->dev, &sdev->mode);
590         if (!mode)
591                 return 0;
592
593         if (mode->name[0] == '\0')
594                 drm_mode_set_name(mode);
595
596         mode->type |= DRM_MODE_TYPE_PREFERRED;
597         drm_mode_probed_add(connector, mode);
598
599         if (mode->width_mm)
600                 connector->display_info.width_mm = mode->width_mm;
601         if (mode->height_mm)
602                 connector->display_info.height_mm = mode->height_mm;
603
604         return 1;
605 }
606
607 static const struct drm_connector_helper_funcs simpledrm_connector_helper_funcs = {
608         .get_modes = simpledrm_connector_helper_get_modes,
609 };
610
611 static const struct drm_connector_funcs simpledrm_connector_funcs = {
612         .reset = drm_atomic_helper_connector_reset,
613         .fill_modes = drm_helper_probe_single_connector_modes,
614         .destroy = drm_connector_cleanup,
615         .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
616         .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
617 };
618
619 static int
620 simpledrm_simple_display_pipe_mode_valid(struct drm_simple_display_pipe *pipe,
621                                     const struct drm_display_mode *mode)
622 {
623         struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev);
624
625         if (mode->hdisplay != sdev->mode.hdisplay &&
626             mode->vdisplay != sdev->mode.vdisplay)
627                 return MODE_ONE_SIZE;
628         else if (mode->hdisplay != sdev->mode.hdisplay)
629                 return MODE_ONE_WIDTH;
630         else if (mode->vdisplay != sdev->mode.vdisplay)
631                 return MODE_ONE_HEIGHT;
632
633         return MODE_OK;
634 }
635
636 static void
637 simpledrm_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
638                                      struct drm_crtc_state *crtc_state,
639                                      struct drm_plane_state *plane_state)
640 {
641         struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev);
642         struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
643         struct drm_framebuffer *fb = plane_state->fb;
644         void *vmap = shadow_plane_state->map[0].vaddr; /* TODO: Use mapping abstraction properly */
645         struct drm_device *dev = &sdev->dev;
646         int idx;
647
648         if (!fb)
649                 return;
650
651         if (!drm_dev_enter(dev, &idx))
652                 return;
653
654         drm_fb_blit_dstclip(sdev->screen_base, sdev->pitch,
655                             sdev->format->format, vmap, fb);
656         drm_dev_exit(idx);
657 }
658
659 static void
660 simpledrm_simple_display_pipe_disable(struct drm_simple_display_pipe *pipe)
661 {
662         struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev);
663         struct drm_device *dev = &sdev->dev;
664         int idx;
665
666         if (!drm_dev_enter(dev, &idx))
667                 return;
668
669         /* Clear screen to black if disabled */
670         memset_io(sdev->screen_base, 0, sdev->pitch * sdev->mode.vdisplay);
671
672         drm_dev_exit(idx);
673 }
674
675 static void
676 simpledrm_simple_display_pipe_update(struct drm_simple_display_pipe *pipe,
677                                      struct drm_plane_state *old_plane_state)
678 {
679         struct simpledrm_device *sdev = simpledrm_device_of_dev(pipe->crtc.dev);
680         struct drm_plane_state *plane_state = pipe->plane.state;
681         struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
682         void *vmap = shadow_plane_state->map[0].vaddr; /* TODO: Use mapping abstraction properly */
683         struct drm_framebuffer *fb = plane_state->fb;
684         struct drm_device *dev = &sdev->dev;
685         struct drm_rect clip;
686         int idx;
687
688         if (!fb)
689                 return;
690
691         if (!drm_atomic_helper_damage_merged(old_plane_state, plane_state, &clip))
692                 return;
693
694         if (!drm_dev_enter(dev, &idx))
695                 return;
696
697         drm_fb_blit_rect_dstclip(sdev->screen_base, sdev->pitch,
698                                  sdev->format->format, vmap, fb, &clip);
699
700         drm_dev_exit(idx);
701 }
702
703 static const struct drm_simple_display_pipe_funcs
704 simpledrm_simple_display_pipe_funcs = {
705         .mode_valid = simpledrm_simple_display_pipe_mode_valid,
706         .enable = simpledrm_simple_display_pipe_enable,
707         .disable = simpledrm_simple_display_pipe_disable,
708         .update = simpledrm_simple_display_pipe_update,
709         DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS,
710 };
711
712 static const struct drm_mode_config_funcs simpledrm_mode_config_funcs = {
713         .fb_create = drm_gem_fb_create_with_dirty,
714         .atomic_check = drm_atomic_helper_check,
715         .atomic_commit = drm_atomic_helper_commit,
716 };
717
718 static const uint32_t *simpledrm_device_formats(struct simpledrm_device *sdev,
719                                                 size_t *nformats_out)
720 {
721         struct drm_device *dev = &sdev->dev;
722         size_t i;
723
724         if (sdev->nformats)
725                 goto out; /* don't rebuild list on recurring calls */
726
727         /* native format goes first */
728         sdev->formats[0] = sdev->format->format;
729         sdev->nformats = 1;
730
731         /* default formats go second */
732         for (i = 0; i < ARRAY_SIZE(simpledrm_default_formats); ++i) {
733                 if (simpledrm_default_formats[i] == sdev->format->format)
734                         continue; /* native format already went first */
735                 sdev->formats[sdev->nformats] = simpledrm_default_formats[i];
736                 sdev->nformats++;
737         }
738
739         /*
740          * TODO: The simpledrm driver converts framebuffers to the native
741          * format when copying them to device memory. If there are more
742          * formats listed than supported by the driver, the native format
743          * is not supported by the conversion helpers. Therefore *only*
744          * support the native format and add a conversion helper ASAP.
745          */
746         if (drm_WARN_ONCE(dev, i != sdev->nformats,
747                           "format conversion helpers required for %p4cc",
748                           &sdev->format->format)) {
749                 sdev->nformats = 1;
750         }
751
752 out:
753         *nformats_out = sdev->nformats;
754         return sdev->formats;
755 }
756
757 static int simpledrm_device_init_modeset(struct simpledrm_device *sdev)
758 {
759         struct drm_device *dev = &sdev->dev;
760         struct drm_display_mode *mode = &sdev->mode;
761         struct drm_connector *connector = &sdev->connector;
762         struct drm_simple_display_pipe *pipe = &sdev->pipe;
763         const uint32_t *formats;
764         size_t nformats;
765         int ret;
766
767         ret = drmm_mode_config_init(dev);
768         if (ret)
769                 return ret;
770
771         dev->mode_config.min_width = mode->hdisplay;
772         dev->mode_config.max_width = mode->hdisplay;
773         dev->mode_config.min_height = mode->vdisplay;
774         dev->mode_config.max_height = mode->vdisplay;
775         dev->mode_config.prefer_shadow_fbdev = true;
776         dev->mode_config.preferred_depth = sdev->format->cpp[0] * 8;
777         dev->mode_config.funcs = &simpledrm_mode_config_funcs;
778
779         ret = drm_connector_init(dev, connector, &simpledrm_connector_funcs,
780                                  DRM_MODE_CONNECTOR_Unknown);
781         if (ret)
782                 return ret;
783         drm_connector_helper_add(connector, &simpledrm_connector_helper_funcs);
784
785         formats = simpledrm_device_formats(sdev, &nformats);
786
787         ret = drm_simple_display_pipe_init(dev, pipe, &simpledrm_simple_display_pipe_funcs,
788                                            formats, nformats, simpledrm_format_modifiers,
789                                            connector);
790         if (ret)
791                 return ret;
792
793         drm_mode_config_reset(dev);
794
795         return 0;
796 }
797
798 /*
799  * Init / Cleanup
800  */
801
802 static struct simpledrm_device *
803 simpledrm_device_create(struct drm_driver *drv, struct platform_device *pdev)
804 {
805         struct simpledrm_device *sdev;
806         int ret;
807
808         sdev = devm_drm_dev_alloc(&pdev->dev, drv, struct simpledrm_device,
809                                   dev);
810         if (IS_ERR(sdev))
811                 return ERR_CAST(sdev);
812         sdev->pdev = pdev;
813         platform_set_drvdata(pdev, sdev);
814
815         ret = simpledrm_device_init_clocks(sdev);
816         if (ret)
817                 return ERR_PTR(ret);
818         ret = simpledrm_device_init_regulators(sdev);
819         if (ret)
820                 return ERR_PTR(ret);
821         ret = simpledrm_device_init_fb(sdev);
822         if (ret)
823                 return ERR_PTR(ret);
824         ret = simpledrm_device_init_mm(sdev);
825         if (ret)
826                 return ERR_PTR(ret);
827         ret = simpledrm_device_init_modeset(sdev);
828         if (ret)
829                 return ERR_PTR(ret);
830
831         return sdev;
832 }
833
834 /*
835  * DRM driver
836  */
837
838 DEFINE_DRM_GEM_FOPS(simpledrm_fops);
839
840 static struct drm_driver simpledrm_driver = {
841         DRM_GEM_SHMEM_DRIVER_OPS,
842         .name                   = DRIVER_NAME,
843         .desc                   = DRIVER_DESC,
844         .date                   = DRIVER_DATE,
845         .major                  = DRIVER_MAJOR,
846         .minor                  = DRIVER_MINOR,
847         .driver_features        = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
848         .fops                   = &simpledrm_fops,
849 };
850
851 /*
852  * Platform driver
853  */
854
855 static int simpledrm_probe(struct platform_device *pdev)
856 {
857         struct simpledrm_device *sdev;
858         struct drm_device *dev;
859         int ret;
860
861         sdev = simpledrm_device_create(&simpledrm_driver, pdev);
862         if (IS_ERR(sdev))
863                 return PTR_ERR(sdev);
864         dev = &sdev->dev;
865
866         ret = drm_dev_register(dev, 0);
867         if (ret)
868                 return ret;
869
870         drm_fbdev_generic_setup(dev, 0);
871
872         return 0;
873 }
874
875 static int simpledrm_remove(struct platform_device *pdev)
876 {
877         struct simpledrm_device *sdev = platform_get_drvdata(pdev);
878         struct drm_device *dev = &sdev->dev;
879
880         drm_dev_unplug(dev);
881
882         return 0;
883 }
884
885 static const struct of_device_id simpledrm_of_match_table[] = {
886         { .compatible = "simple-framebuffer", },
887         { },
888 };
889 MODULE_DEVICE_TABLE(of, simpledrm_of_match_table);
890
891 static struct platform_driver simpledrm_platform_driver = {
892         .driver = {
893                 .name = "simple-framebuffer", /* connect to sysfb */
894                 .of_match_table = simpledrm_of_match_table,
895         },
896         .probe = simpledrm_probe,
897         .remove = simpledrm_remove,
898 };
899
900 module_platform_driver(simpledrm_platform_driver);
901
902 MODULE_DESCRIPTION(DRIVER_DESC);
903 MODULE_LICENSE("GPL v2");