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