xref: /openbmc/linux/drivers/video/fbdev/simplefb.c (revision 04b3c795)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Simplest possible simple frame-buffer driver, as a platform device
4  *
5  * Copyright (c) 2013, Stephen Warren
6  *
7  * Based on q40fb.c, which was:
8  * Copyright (C) 2001 Richard Zidlicky <rz@linux-m68k.org>
9  *
10  * Also based on offb.c, which was:
11  * Copyright (C) 1997 Geert Uytterhoeven
12  * Copyright (C) 1996 Paul Mackerras
13  */
14 
15 #include <linux/errno.h>
16 #include <linux/fb.h>
17 #include <linux/io.h>
18 #include <linux/module.h>
19 #include <linux/platform_data/simplefb.h>
20 #include <linux/platform_device.h>
21 #include <linux/clk.h>
22 #include <linux/of.h>
23 #include <linux/of_clk.h>
24 #include <linux/of_platform.h>
25 #include <linux/parser.h>
26 #include <linux/regulator/consumer.h>
27 
28 static const struct fb_fix_screeninfo simplefb_fix = {
29 	.id		= "simple",
30 	.type		= FB_TYPE_PACKED_PIXELS,
31 	.visual		= FB_VISUAL_TRUECOLOR,
32 	.accel		= FB_ACCEL_NONE,
33 };
34 
35 static const struct fb_var_screeninfo simplefb_var = {
36 	.height		= -1,
37 	.width		= -1,
38 	.activate	= FB_ACTIVATE_NOW,
39 	.vmode		= FB_VMODE_NONINTERLACED,
40 };
41 
42 #define PSEUDO_PALETTE_SIZE 16
43 
44 static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
45 			      u_int transp, struct fb_info *info)
46 {
47 	u32 *pal = info->pseudo_palette;
48 	u32 cr = red >> (16 - info->var.red.length);
49 	u32 cg = green >> (16 - info->var.green.length);
50 	u32 cb = blue >> (16 - info->var.blue.length);
51 	u32 value;
52 
53 	if (regno >= PSEUDO_PALETTE_SIZE)
54 		return -EINVAL;
55 
56 	value = (cr << info->var.red.offset) |
57 		(cg << info->var.green.offset) |
58 		(cb << info->var.blue.offset);
59 	if (info->var.transp.length > 0) {
60 		u32 mask = (1 << info->var.transp.length) - 1;
61 		mask <<= info->var.transp.offset;
62 		value |= mask;
63 	}
64 	pal[regno] = value;
65 
66 	return 0;
67 }
68 
69 struct simplefb_par;
70 static void simplefb_clocks_destroy(struct simplefb_par *par);
71 static void simplefb_regulators_destroy(struct simplefb_par *par);
72 
73 static void simplefb_destroy(struct fb_info *info)
74 {
75 	simplefb_regulators_destroy(info->par);
76 	simplefb_clocks_destroy(info->par);
77 	if (info->screen_base)
78 		iounmap(info->screen_base);
79 }
80 
81 static const struct fb_ops simplefb_ops = {
82 	.owner		= THIS_MODULE,
83 	.fb_destroy	= simplefb_destroy,
84 	.fb_setcolreg	= simplefb_setcolreg,
85 	.fb_fillrect	= cfb_fillrect,
86 	.fb_copyarea	= cfb_copyarea,
87 	.fb_imageblit	= cfb_imageblit,
88 };
89 
90 static struct simplefb_format simplefb_formats[] = SIMPLEFB_FORMATS;
91 
92 struct simplefb_params {
93 	u32 width;
94 	u32 height;
95 	u32 stride;
96 	struct simplefb_format *format;
97 };
98 
99 static int simplefb_parse_dt(struct platform_device *pdev,
100 			   struct simplefb_params *params)
101 {
102 	struct device_node *np = pdev->dev.of_node;
103 	int ret;
104 	const char *format;
105 	int i;
106 
107 	ret = of_property_read_u32(np, "width", &params->width);
108 	if (ret) {
109 		dev_err(&pdev->dev, "Can't parse width property\n");
110 		return ret;
111 	}
112 
113 	ret = of_property_read_u32(np, "height", &params->height);
114 	if (ret) {
115 		dev_err(&pdev->dev, "Can't parse height property\n");
116 		return ret;
117 	}
118 
119 	ret = of_property_read_u32(np, "stride", &params->stride);
120 	if (ret) {
121 		dev_err(&pdev->dev, "Can't parse stride property\n");
122 		return ret;
123 	}
124 
125 	ret = of_property_read_string(np, "format", &format);
126 	if (ret) {
127 		dev_err(&pdev->dev, "Can't parse format property\n");
128 		return ret;
129 	}
130 	params->format = NULL;
131 	for (i = 0; i < ARRAY_SIZE(simplefb_formats); i++) {
132 		if (strcmp(format, simplefb_formats[i].name))
133 			continue;
134 		params->format = &simplefb_formats[i];
135 		break;
136 	}
137 	if (!params->format) {
138 		dev_err(&pdev->dev, "Invalid format value\n");
139 		return -EINVAL;
140 	}
141 
142 	return 0;
143 }
144 
145 static int simplefb_parse_pd(struct platform_device *pdev,
146 			     struct simplefb_params *params)
147 {
148 	struct simplefb_platform_data *pd = dev_get_platdata(&pdev->dev);
149 	int i;
150 
151 	params->width = pd->width;
152 	params->height = pd->height;
153 	params->stride = pd->stride;
154 
155 	params->format = NULL;
156 	for (i = 0; i < ARRAY_SIZE(simplefb_formats); i++) {
157 		if (strcmp(pd->format, simplefb_formats[i].name))
158 			continue;
159 
160 		params->format = &simplefb_formats[i];
161 		break;
162 	}
163 
164 	if (!params->format) {
165 		dev_err(&pdev->dev, "Invalid format value\n");
166 		return -EINVAL;
167 	}
168 
169 	return 0;
170 }
171 
172 struct simplefb_par {
173 	u32 palette[PSEUDO_PALETTE_SIZE];
174 #if defined CONFIG_OF && defined CONFIG_COMMON_CLK
175 	bool clks_enabled;
176 	unsigned int clk_count;
177 	struct clk **clks;
178 #endif
179 #if defined CONFIG_OF && defined CONFIG_REGULATOR
180 	bool regulators_enabled;
181 	u32 regulator_count;
182 	struct regulator **regulators;
183 #endif
184 };
185 
186 #if defined CONFIG_OF && defined CONFIG_COMMON_CLK
187 /*
188  * Clock handling code.
189  *
190  * Here we handle the clocks property of our "simple-framebuffer" dt node.
191  * This is necessary so that we can make sure that any clocks needed by
192  * the display engine that the bootloader set up for us (and for which it
193  * provided a simplefb dt node), stay up, for the life of the simplefb
194  * driver.
195  *
196  * When the driver unloads, we cleanly disable, and then release the clocks.
197  *
198  * We only complain about errors here, no action is taken as the most likely
199  * error can only happen due to a mismatch between the bootloader which set
200  * up simplefb, and the clock definitions in the device tree. Chances are
201  * that there are no adverse effects, and if there are, a clean teardown of
202  * the fb probe will not help us much either. So just complain and carry on,
203  * and hope that the user actually gets a working fb at the end of things.
204  */
205 static int simplefb_clocks_get(struct simplefb_par *par,
206 			       struct platform_device *pdev)
207 {
208 	struct device_node *np = pdev->dev.of_node;
209 	struct clk *clock;
210 	int i;
211 
212 	if (dev_get_platdata(&pdev->dev) || !np)
213 		return 0;
214 
215 	par->clk_count = of_clk_get_parent_count(np);
216 	if (!par->clk_count)
217 		return 0;
218 
219 	par->clks = kcalloc(par->clk_count, sizeof(struct clk *), GFP_KERNEL);
220 	if (!par->clks)
221 		return -ENOMEM;
222 
223 	for (i = 0; i < par->clk_count; i++) {
224 		clock = of_clk_get(np, i);
225 		if (IS_ERR(clock)) {
226 			if (PTR_ERR(clock) == -EPROBE_DEFER) {
227 				while (--i >= 0) {
228 					if (par->clks[i])
229 						clk_put(par->clks[i]);
230 				}
231 				kfree(par->clks);
232 				return -EPROBE_DEFER;
233 			}
234 			dev_err(&pdev->dev, "%s: clock %d not found: %ld\n",
235 				__func__, i, PTR_ERR(clock));
236 			continue;
237 		}
238 		par->clks[i] = clock;
239 	}
240 
241 	return 0;
242 }
243 
244 static void simplefb_clocks_enable(struct simplefb_par *par,
245 				   struct platform_device *pdev)
246 {
247 	int i, ret;
248 
249 	for (i = 0; i < par->clk_count; i++) {
250 		if (par->clks[i]) {
251 			ret = clk_prepare_enable(par->clks[i]);
252 			if (ret) {
253 				dev_err(&pdev->dev,
254 					"%s: failed to enable clock %d: %d\n",
255 					__func__, i, ret);
256 				clk_put(par->clks[i]);
257 				par->clks[i] = NULL;
258 			}
259 		}
260 	}
261 	par->clks_enabled = true;
262 }
263 
264 static void simplefb_clocks_destroy(struct simplefb_par *par)
265 {
266 	int i;
267 
268 	if (!par->clks)
269 		return;
270 
271 	for (i = 0; i < par->clk_count; i++) {
272 		if (par->clks[i]) {
273 			if (par->clks_enabled)
274 				clk_disable_unprepare(par->clks[i]);
275 			clk_put(par->clks[i]);
276 		}
277 	}
278 
279 	kfree(par->clks);
280 }
281 #else
282 static int simplefb_clocks_get(struct simplefb_par *par,
283 	struct platform_device *pdev) { return 0; }
284 static void simplefb_clocks_enable(struct simplefb_par *par,
285 	struct platform_device *pdev) { }
286 static void simplefb_clocks_destroy(struct simplefb_par *par) { }
287 #endif
288 
289 #if defined CONFIG_OF && defined CONFIG_REGULATOR
290 
291 #define SUPPLY_SUFFIX "-supply"
292 
293 /*
294  * Regulator handling code.
295  *
296  * Here we handle the num-supplies and vin*-supply properties of our
297  * "simple-framebuffer" dt node. This is necessary so that we can make sure
298  * that any regulators needed by the display hardware that the bootloader
299  * set up for us (and for which it provided a simplefb dt node), stay up,
300  * for the life of the simplefb driver.
301  *
302  * When the driver unloads, we cleanly disable, and then release the
303  * regulators.
304  *
305  * We only complain about errors here, no action is taken as the most likely
306  * error can only happen due to a mismatch between the bootloader which set
307  * up simplefb, and the regulator definitions in the device tree. Chances are
308  * that there are no adverse effects, and if there are, a clean teardown of
309  * the fb probe will not help us much either. So just complain and carry on,
310  * and hope that the user actually gets a working fb at the end of things.
311  */
312 static int simplefb_regulators_get(struct simplefb_par *par,
313 				   struct platform_device *pdev)
314 {
315 	struct device_node *np = pdev->dev.of_node;
316 	struct property *prop;
317 	struct regulator *regulator;
318 	const char *p;
319 	int count = 0, i = 0;
320 
321 	if (dev_get_platdata(&pdev->dev) || !np)
322 		return 0;
323 
324 	/* Count the number of regulator supplies */
325 	for_each_property_of_node(np, prop) {
326 		p = strstr(prop->name, SUPPLY_SUFFIX);
327 		if (p && p != prop->name)
328 			count++;
329 	}
330 
331 	if (!count)
332 		return 0;
333 
334 	par->regulators = devm_kcalloc(&pdev->dev, count,
335 				       sizeof(struct regulator *), GFP_KERNEL);
336 	if (!par->regulators)
337 		return -ENOMEM;
338 
339 	/* Get all the regulators */
340 	for_each_property_of_node(np, prop) {
341 		char name[32]; /* 32 is max size of property name */
342 
343 		p = strstr(prop->name, SUPPLY_SUFFIX);
344 		if (!p || p == prop->name)
345 			continue;
346 
347 		strlcpy(name, prop->name,
348 			strlen(prop->name) - strlen(SUPPLY_SUFFIX) + 1);
349 		regulator = devm_regulator_get_optional(&pdev->dev, name);
350 		if (IS_ERR(regulator)) {
351 			if (PTR_ERR(regulator) == -EPROBE_DEFER)
352 				return -EPROBE_DEFER;
353 			dev_err(&pdev->dev, "regulator %s not found: %ld\n",
354 				name, PTR_ERR(regulator));
355 			continue;
356 		}
357 		par->regulators[i++] = regulator;
358 	}
359 	par->regulator_count = i;
360 
361 	return 0;
362 }
363 
364 static void simplefb_regulators_enable(struct simplefb_par *par,
365 				       struct platform_device *pdev)
366 {
367 	int i, ret;
368 
369 	/* Enable all the regulators */
370 	for (i = 0; i < par->regulator_count; i++) {
371 		ret = regulator_enable(par->regulators[i]);
372 		if (ret) {
373 			dev_err(&pdev->dev,
374 				"failed to enable regulator %d: %d\n",
375 				i, ret);
376 			devm_regulator_put(par->regulators[i]);
377 			par->regulators[i] = NULL;
378 		}
379 	}
380 	par->regulators_enabled = true;
381 }
382 
383 static void simplefb_regulators_destroy(struct simplefb_par *par)
384 {
385 	int i;
386 
387 	if (!par->regulators || !par->regulators_enabled)
388 		return;
389 
390 	for (i = 0; i < par->regulator_count; i++)
391 		if (par->regulators[i])
392 			regulator_disable(par->regulators[i]);
393 }
394 #else
395 static int simplefb_regulators_get(struct simplefb_par *par,
396 	struct platform_device *pdev) { return 0; }
397 static void simplefb_regulators_enable(struct simplefb_par *par,
398 	struct platform_device *pdev) { }
399 static void simplefb_regulators_destroy(struct simplefb_par *par) { }
400 #endif
401 
402 static int simplefb_probe(struct platform_device *pdev)
403 {
404 	int ret;
405 	struct simplefb_params params;
406 	struct fb_info *info;
407 	struct simplefb_par *par;
408 	struct resource *mem;
409 
410 	if (fb_get_options("simplefb", NULL))
411 		return -ENODEV;
412 
413 	ret = -ENODEV;
414 	if (dev_get_platdata(&pdev->dev))
415 		ret = simplefb_parse_pd(pdev, &params);
416 	else if (pdev->dev.of_node)
417 		ret = simplefb_parse_dt(pdev, &params);
418 
419 	if (ret)
420 		return ret;
421 
422 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
423 	if (!mem) {
424 		dev_err(&pdev->dev, "No memory resource\n");
425 		return -EINVAL;
426 	}
427 
428 	info = framebuffer_alloc(sizeof(struct simplefb_par), &pdev->dev);
429 	if (!info)
430 		return -ENOMEM;
431 	platform_set_drvdata(pdev, info);
432 
433 	par = info->par;
434 
435 	info->fix = simplefb_fix;
436 	info->fix.smem_start = mem->start;
437 	info->fix.smem_len = resource_size(mem);
438 	info->fix.line_length = params.stride;
439 
440 	info->var = simplefb_var;
441 	info->var.xres = params.width;
442 	info->var.yres = params.height;
443 	info->var.xres_virtual = params.width;
444 	info->var.yres_virtual = params.height;
445 	info->var.bits_per_pixel = params.format->bits_per_pixel;
446 	info->var.red = params.format->red;
447 	info->var.green = params.format->green;
448 	info->var.blue = params.format->blue;
449 	info->var.transp = params.format->transp;
450 
451 	info->apertures = alloc_apertures(1);
452 	if (!info->apertures) {
453 		ret = -ENOMEM;
454 		goto error_fb_release;
455 	}
456 	info->apertures->ranges[0].base = info->fix.smem_start;
457 	info->apertures->ranges[0].size = info->fix.smem_len;
458 
459 	info->fbops = &simplefb_ops;
460 	info->flags = FBINFO_DEFAULT | FBINFO_MISC_FIRMWARE;
461 	info->screen_base = ioremap_wc(info->fix.smem_start,
462 				       info->fix.smem_len);
463 	if (!info->screen_base) {
464 		ret = -ENOMEM;
465 		goto error_fb_release;
466 	}
467 	info->pseudo_palette = par->palette;
468 
469 	ret = simplefb_clocks_get(par, pdev);
470 	if (ret < 0)
471 		goto error_unmap;
472 
473 	ret = simplefb_regulators_get(par, pdev);
474 	if (ret < 0)
475 		goto error_clocks;
476 
477 	simplefb_clocks_enable(par, pdev);
478 	simplefb_regulators_enable(par, pdev);
479 
480 	dev_info(&pdev->dev, "framebuffer at 0x%lx, 0x%x bytes, mapped to 0x%p\n",
481 			     info->fix.smem_start, info->fix.smem_len,
482 			     info->screen_base);
483 	dev_info(&pdev->dev, "format=%s, mode=%dx%dx%d, linelength=%d\n",
484 			     params.format->name,
485 			     info->var.xres, info->var.yres,
486 			     info->var.bits_per_pixel, info->fix.line_length);
487 
488 	ret = register_framebuffer(info);
489 	if (ret < 0) {
490 		dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret);
491 		goto error_regulators;
492 	}
493 
494 	dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node);
495 
496 	return 0;
497 
498 error_regulators:
499 	simplefb_regulators_destroy(par);
500 error_clocks:
501 	simplefb_clocks_destroy(par);
502 error_unmap:
503 	iounmap(info->screen_base);
504 error_fb_release:
505 	framebuffer_release(info);
506 	return ret;
507 }
508 
509 static int simplefb_remove(struct platform_device *pdev)
510 {
511 	struct fb_info *info = platform_get_drvdata(pdev);
512 
513 	unregister_framebuffer(info);
514 	framebuffer_release(info);
515 
516 	return 0;
517 }
518 
519 static const struct of_device_id simplefb_of_match[] = {
520 	{ .compatible = "simple-framebuffer", },
521 	{ },
522 };
523 MODULE_DEVICE_TABLE(of, simplefb_of_match);
524 
525 static struct platform_driver simplefb_driver = {
526 	.driver = {
527 		.name = "simple-framebuffer",
528 		.of_match_table = simplefb_of_match,
529 	},
530 	.probe = simplefb_probe,
531 	.remove = simplefb_remove,
532 };
533 
534 static int __init simplefb_init(void)
535 {
536 	int ret;
537 	struct device_node *np;
538 
539 	ret = platform_driver_register(&simplefb_driver);
540 	if (ret)
541 		return ret;
542 
543 	if (IS_ENABLED(CONFIG_OF_ADDRESS) && of_chosen) {
544 		for_each_child_of_node(of_chosen, np) {
545 			if (of_device_is_compatible(np, "simple-framebuffer"))
546 				of_platform_device_create(np, NULL, NULL);
547 		}
548 	}
549 
550 	return 0;
551 }
552 
553 fs_initcall(simplefb_init);
554 
555 MODULE_AUTHOR("Stephen Warren <swarren@wwwdotorg.org>");
556 MODULE_DESCRIPTION("Simple framebuffer driver");
557 MODULE_LICENSE("GPL v2");
558