Lines Matching +full:simple +full:- +full:framebuffer

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Simplest possible simple frame-buffer driver, as a platform device
8 * Copyright (C) 2001 Richard Zidlicky <rz@linux-m68k.org>
32 .id = "simple",
39 .height = -1,
40 .width = -1,
50 u32 *pal = info->pseudo_palette; in simplefb_setcolreg()
51 u32 cr = red >> (16 - info->var.red.length); in simplefb_setcolreg()
52 u32 cg = green >> (16 - info->var.green.length); in simplefb_setcolreg()
53 u32 cb = blue >> (16 - info->var.blue.length); in simplefb_setcolreg()
57 return -EINVAL; in simplefb_setcolreg()
59 value = (cr << info->var.red.offset) | in simplefb_setcolreg()
60 (cg << info->var.green.offset) | in simplefb_setcolreg()
61 (cb << info->var.blue.offset); in simplefb_setcolreg()
62 if (info->var.transp.length > 0) { in simplefb_setcolreg()
63 u32 mask = (1 << info->var.transp.length) - 1; in simplefb_setcolreg()
64 mask <<= info->var.transp.offset; in simplefb_setcolreg()
103 struct simplefb_par *par = info->par; in simplefb_destroy()
104 struct resource *mem = par->mem; in simplefb_destroy()
106 simplefb_regulators_destroy(info->par); in simplefb_destroy()
107 simplefb_clocks_destroy(info->par); in simplefb_destroy()
108 if (info->screen_base) in simplefb_destroy()
109 iounmap(info->screen_base); in simplefb_destroy()
114 release_mem_region(mem->start, resource_size(mem)); in simplefb_destroy()
137 struct device_node *np = pdev->dev.of_node, *mem; in simplefb_parse_dt()
142 ret = of_property_read_u32(np, "width", &params->width); in simplefb_parse_dt()
144 dev_err(&pdev->dev, "Can't parse width property\n"); in simplefb_parse_dt()
148 ret = of_property_read_u32(np, "height", &params->height); in simplefb_parse_dt()
150 dev_err(&pdev->dev, "Can't parse height property\n"); in simplefb_parse_dt()
154 ret = of_property_read_u32(np, "stride", &params->stride); in simplefb_parse_dt()
156 dev_err(&pdev->dev, "Can't parse stride property\n"); in simplefb_parse_dt()
162 dev_err(&pdev->dev, "Can't parse format property\n"); in simplefb_parse_dt()
165 params->format = NULL; in simplefb_parse_dt()
169 params->format = &simplefb_formats[i]; in simplefb_parse_dt()
172 if (!params->format) { in simplefb_parse_dt()
173 dev_err(&pdev->dev, "Invalid format value\n"); in simplefb_parse_dt()
174 return -EINVAL; in simplefb_parse_dt()
177 mem = of_parse_phandle(np, "memory-region", 0); in simplefb_parse_dt()
179 ret = of_address_to_resource(mem, 0, &params->memory); in simplefb_parse_dt()
181 dev_err(&pdev->dev, "failed to parse memory-region\n"); in simplefb_parse_dt()
187 dev_warn(&pdev->dev, "preferring \"memory-region\" over \"reg\" property\n"); in simplefb_parse_dt()
191 memset(&params->memory, 0, sizeof(params->memory)); in simplefb_parse_dt()
200 struct simplefb_platform_data *pd = dev_get_platdata(&pdev->dev); in simplefb_parse_pd()
203 params->width = pd->width; in simplefb_parse_pd()
204 params->height = pd->height; in simplefb_parse_pd()
205 params->stride = pd->stride; in simplefb_parse_pd()
207 params->format = NULL; in simplefb_parse_pd()
209 if (strcmp(pd->format, simplefb_formats[i].name)) in simplefb_parse_pd()
212 params->format = &simplefb_formats[i]; in simplefb_parse_pd()
216 if (!params->format) { in simplefb_parse_pd()
217 dev_err(&pdev->dev, "Invalid format value\n"); in simplefb_parse_pd()
218 return -EINVAL; in simplefb_parse_pd()
221 memset(&params->memory, 0, sizeof(params->memory)); in simplefb_parse_pd()
230 * Here we handle the clocks property of our "simple-framebuffer" dt node.
248 struct device_node *np = pdev->dev.of_node; in simplefb_clocks_get()
252 if (dev_get_platdata(&pdev->dev) || !np) in simplefb_clocks_get()
255 par->clk_count = of_clk_get_parent_count(np); in simplefb_clocks_get()
256 if (!par->clk_count) in simplefb_clocks_get()
259 par->clks = kcalloc(par->clk_count, sizeof(struct clk *), GFP_KERNEL); in simplefb_clocks_get()
260 if (!par->clks) in simplefb_clocks_get()
261 return -ENOMEM; in simplefb_clocks_get()
263 for (i = 0; i < par->clk_count; i++) { in simplefb_clocks_get()
266 if (PTR_ERR(clock) == -EPROBE_DEFER) { in simplefb_clocks_get()
267 while (--i >= 0) { in simplefb_clocks_get()
268 clk_put(par->clks[i]); in simplefb_clocks_get()
270 kfree(par->clks); in simplefb_clocks_get()
271 return -EPROBE_DEFER; in simplefb_clocks_get()
273 dev_err(&pdev->dev, "%s: clock %d not found: %ld\n", in simplefb_clocks_get()
277 par->clks[i] = clock; in simplefb_clocks_get()
288 for (i = 0; i < par->clk_count; i++) { in simplefb_clocks_enable()
289 if (par->clks[i]) { in simplefb_clocks_enable()
290 ret = clk_prepare_enable(par->clks[i]); in simplefb_clocks_enable()
292 dev_err(&pdev->dev, in simplefb_clocks_enable()
295 clk_put(par->clks[i]); in simplefb_clocks_enable()
296 par->clks[i] = NULL; in simplefb_clocks_enable()
300 par->clks_enabled = true; in simplefb_clocks_enable()
307 if (!par->clks) in simplefb_clocks_destroy()
310 for (i = 0; i < par->clk_count; i++) { in simplefb_clocks_destroy()
311 if (par->clks[i]) { in simplefb_clocks_destroy()
312 if (par->clks_enabled) in simplefb_clocks_destroy()
313 clk_disable_unprepare(par->clks[i]); in simplefb_clocks_destroy()
314 clk_put(par->clks[i]); in simplefb_clocks_destroy()
318 kfree(par->clks); in simplefb_clocks_destroy()
330 #define SUPPLY_SUFFIX "-supply"
335 * Here we handle the num-supplies and vin*-supply properties of our
336 * "simple-framebuffer" dt node. This is necessary so that we can make sure
354 struct device_node *np = pdev->dev.of_node; in simplefb_regulators_get()
360 if (dev_get_platdata(&pdev->dev) || !np) in simplefb_regulators_get()
365 p = strstr(prop->name, SUPPLY_SUFFIX); in simplefb_regulators_get()
366 if (p && p != prop->name) in simplefb_regulators_get()
373 par->regulators = devm_kcalloc(&pdev->dev, count, in simplefb_regulators_get()
375 if (!par->regulators) in simplefb_regulators_get()
376 return -ENOMEM; in simplefb_regulators_get()
382 p = strstr(prop->name, SUPPLY_SUFFIX); in simplefb_regulators_get()
383 if (!p || p == prop->name) in simplefb_regulators_get()
386 strscpy(name, prop->name, in simplefb_regulators_get()
387 strlen(prop->name) - strlen(SUPPLY_SUFFIX) + 1); in simplefb_regulators_get()
388 regulator = devm_regulator_get_optional(&pdev->dev, name); in simplefb_regulators_get()
390 if (PTR_ERR(regulator) == -EPROBE_DEFER) in simplefb_regulators_get()
391 return -EPROBE_DEFER; in simplefb_regulators_get()
392 dev_err(&pdev->dev, "regulator %s not found: %ld\n", in simplefb_regulators_get()
396 par->regulators[i++] = regulator; in simplefb_regulators_get()
398 par->regulator_count = i; in simplefb_regulators_get()
409 for (i = 0; i < par->regulator_count; i++) { in simplefb_regulators_enable()
410 ret = regulator_enable(par->regulators[i]); in simplefb_regulators_enable()
412 dev_err(&pdev->dev, in simplefb_regulators_enable()
415 devm_regulator_put(par->regulators[i]); in simplefb_regulators_enable()
416 par->regulators[i] = NULL; in simplefb_regulators_enable()
419 par->regulators_enabled = true; in simplefb_regulators_enable()
426 if (!par->regulators || !par->regulators_enabled) in simplefb_regulators_destroy()
429 for (i = 0; i < par->regulator_count; i++) in simplefb_regulators_destroy()
430 if (par->regulators[i]) in simplefb_regulators_destroy()
431 regulator_disable(par->regulators[i]); in simplefb_regulators_destroy()
445 unsigned int i = par->num_genpds; in simplefb_detach_genpds()
447 if (par->num_genpds <= 1) in simplefb_detach_genpds()
450 while (i--) { in simplefb_detach_genpds()
451 if (par->genpd_links[i]) in simplefb_detach_genpds()
452 device_link_del(par->genpd_links[i]); in simplefb_detach_genpds()
454 if (!IS_ERR_OR_NULL(par->genpds[i])) in simplefb_detach_genpds()
455 dev_pm_domain_detach(par->genpds[i], true); in simplefb_detach_genpds()
462 struct device *dev = &pdev->dev; in simplefb_attach_genpds()
466 err = of_count_phandle_with_args(dev->of_node, "power-domains", in simplefb_attach_genpds()
467 "#power-domain-cells"); in simplefb_attach_genpds()
470 if (err == -ENOENT) in simplefb_attach_genpds()
473 dev_err(dev, "failed to parse power-domains: %d\n", err); in simplefb_attach_genpds()
477 par->num_genpds = err; in simplefb_attach_genpds()
480 * Single power-domain devices are handled by the driver core, so in simplefb_attach_genpds()
483 if (par->num_genpds <= 1) in simplefb_attach_genpds()
486 par->genpds = devm_kcalloc(dev, par->num_genpds, sizeof(*par->genpds), in simplefb_attach_genpds()
488 if (!par->genpds) in simplefb_attach_genpds()
489 return -ENOMEM; in simplefb_attach_genpds()
491 par->genpd_links = devm_kcalloc(dev, par->num_genpds, in simplefb_attach_genpds()
492 sizeof(*par->genpd_links), in simplefb_attach_genpds()
494 if (!par->genpd_links) in simplefb_attach_genpds()
495 return -ENOMEM; in simplefb_attach_genpds()
497 for (i = 0; i < par->num_genpds; i++) { in simplefb_attach_genpds()
498 par->genpds[i] = dev_pm_domain_attach_by_id(dev, i); in simplefb_attach_genpds()
499 if (IS_ERR(par->genpds[i])) { in simplefb_attach_genpds()
500 err = PTR_ERR(par->genpds[i]); in simplefb_attach_genpds()
501 if (err == -EPROBE_DEFER) { in simplefb_attach_genpds()
510 par->genpd_links[i] = device_link_add(dev, par->genpds[i], in simplefb_attach_genpds()
514 if (!par->genpd_links[i]) in simplefb_attach_genpds()
515 dev_warn(dev, "failed to link power-domain %u\n", i); in simplefb_attach_genpds()
537 return -ENODEV; in simplefb_probe()
539 ret = -ENODEV; in simplefb_probe()
540 if (dev_get_platdata(&pdev->dev)) in simplefb_probe()
542 else if (pdev->dev.of_node) in simplefb_probe()
551 dev_err(&pdev->dev, "No memory resource\n"); in simplefb_probe()
552 return -EINVAL; in simplefb_probe()
558 mem = request_mem_region(res->start, resource_size(res), "simplefb"); in simplefb_probe()
563 * the I/O-memory resource as-is and try to map that instead. in simplefb_probe()
565 dev_warn(&pdev->dev, "simplefb: cannot reserve video memory at %pR\n", res); in simplefb_probe()
569 info = framebuffer_alloc(sizeof(struct simplefb_par), &pdev->dev); in simplefb_probe()
571 ret = -ENOMEM; in simplefb_probe()
576 par = info->par; in simplefb_probe()
578 info->fix = simplefb_fix; in simplefb_probe()
579 info->fix.smem_start = mem->start; in simplefb_probe()
580 info->fix.smem_len = resource_size(mem); in simplefb_probe()
581 info->fix.line_length = params.stride; in simplefb_probe()
583 info->var = simplefb_var; in simplefb_probe()
584 info->var.xres = params.width; in simplefb_probe()
585 info->var.yres = params.height; in simplefb_probe()
586 info->var.xres_virtual = params.width; in simplefb_probe()
587 info->var.yres_virtual = params.height; in simplefb_probe()
588 info->var.bits_per_pixel = params.format->bits_per_pixel; in simplefb_probe()
589 info->var.red = params.format->red; in simplefb_probe()
590 info->var.green = params.format->green; in simplefb_probe()
591 info->var.blue = params.format->blue; in simplefb_probe()
592 info->var.transp = params.format->transp; in simplefb_probe()
594 par->base = info->fix.smem_start; in simplefb_probe()
595 par->size = info->fix.smem_len; in simplefb_probe()
597 info->fbops = &simplefb_ops; in simplefb_probe()
598 info->screen_base = ioremap_wc(info->fix.smem_start, in simplefb_probe()
599 info->fix.smem_len); in simplefb_probe()
600 if (!info->screen_base) { in simplefb_probe()
601 ret = -ENOMEM; in simplefb_probe()
604 info->pseudo_palette = par->palette; in simplefb_probe()
621 dev_info(&pdev->dev, "framebuffer at 0x%lx, 0x%x bytes\n", in simplefb_probe()
622 info->fix.smem_start, info->fix.smem_len); in simplefb_probe()
623 dev_info(&pdev->dev, "format=%s, mode=%dx%dx%d, linelength=%d\n", in simplefb_probe()
624 params.format->name, in simplefb_probe()
625 info->var.xres, info->var.yres, in simplefb_probe()
626 info->var.bits_per_pixel, info->fix.line_length); in simplefb_probe()
629 par->mem = mem; /* release in clean-up handler */ in simplefb_probe()
631 ret = devm_aperture_acquire_for_platform_device(pdev, par->base, par->size); in simplefb_probe()
633 dev_err(&pdev->dev, "Unable to acquire aperture: %d\n", ret); in simplefb_probe()
638 dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret); in simplefb_probe()
642 dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node); in simplefb_probe()
651 iounmap(info->screen_base); in simplefb_probe()
656 release_mem_region(mem->start, resource_size(mem)); in simplefb_probe()
669 { .compatible = "simple-framebuffer", },
676 .name = "simple-framebuffer",
686 MODULE_DESCRIPTION("Simple framebuffer driver");