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()
104 struct simplefb_par *par = info->par; in simplefb_destroy()
105 struct resource *mem = par->mem; in simplefb_destroy()
107 simplefb_regulators_destroy(info->par); in simplefb_destroy()
108 simplefb_clocks_destroy(info->par); in simplefb_destroy()
109 simplefb_detach_genpds(info->par); in simplefb_destroy()
110 if (info->screen_base) in simplefb_destroy()
111 iounmap(info->screen_base); in simplefb_destroy()
116 release_mem_region(mem->start, resource_size(mem)); in simplefb_destroy()
139 struct device_node *np = pdev->dev.of_node; in simplefb_parse_dt()
144 ret = of_property_read_u32(np, "width", ¶ms->width); in simplefb_parse_dt()
146 dev_err(&pdev->dev, "Can't parse width property\n"); in simplefb_parse_dt()
150 ret = of_property_read_u32(np, "height", ¶ms->height); in simplefb_parse_dt()
152 dev_err(&pdev->dev, "Can't parse height property\n"); in simplefb_parse_dt()
156 ret = of_property_read_u32(np, "stride", ¶ms->stride); in simplefb_parse_dt()
158 dev_err(&pdev->dev, "Can't parse stride property\n"); in simplefb_parse_dt()
164 dev_err(&pdev->dev, "Can't parse format property\n"); in simplefb_parse_dt()
167 params->format = NULL; in simplefb_parse_dt()
171 params->format = &simplefb_formats[i]; in simplefb_parse_dt()
174 if (!params->format) { in simplefb_parse_dt()
175 dev_err(&pdev->dev, "Invalid format value\n"); in simplefb_parse_dt()
176 return -EINVAL; in simplefb_parse_dt()
179 ret = of_reserved_mem_region_to_resource(np, 0, ¶ms->memory); in simplefb_parse_dt()
182 dev_warn(&pdev->dev, "preferring \"memory-region\" over \"reg\" property\n"); in simplefb_parse_dt()
184 memset(¶ms->memory, 0, sizeof(params->memory)); in simplefb_parse_dt()
193 struct simplefb_platform_data *pd = dev_get_platdata(&pdev->dev); in simplefb_parse_pd()
196 params->width = pd->width; in simplefb_parse_pd()
197 params->height = pd->height; in simplefb_parse_pd()
198 params->stride = pd->stride; in simplefb_parse_pd()
200 params->format = NULL; in simplefb_parse_pd()
202 if (strcmp(pd->format, simplefb_formats[i].name)) in simplefb_parse_pd()
205 params->format = &simplefb_formats[i]; in simplefb_parse_pd()
209 if (!params->format) { in simplefb_parse_pd()
210 dev_err(&pdev->dev, "Invalid format value\n"); in simplefb_parse_pd()
211 return -EINVAL; in simplefb_parse_pd()
214 memset(¶ms->memory, 0, sizeof(params->memory)); in simplefb_parse_pd()
223 * Here we handle the clocks property of our "simple-framebuffer" dt node.
241 struct device_node *np = pdev->dev.of_node; in simplefb_clocks_get()
245 if (dev_get_platdata(&pdev->dev) || !np) in simplefb_clocks_get()
248 par->clk_count = of_clk_get_parent_count(np); in simplefb_clocks_get()
249 if (!par->clk_count) in simplefb_clocks_get()
252 par->clks = kcalloc(par->clk_count, sizeof(struct clk *), GFP_KERNEL); in simplefb_clocks_get()
253 if (!par->clks) in simplefb_clocks_get()
254 return -ENOMEM; in simplefb_clocks_get()
256 for (i = 0; i < par->clk_count; i++) { in simplefb_clocks_get()
259 if (PTR_ERR(clock) == -EPROBE_DEFER) { in simplefb_clocks_get()
260 while (--i >= 0) { in simplefb_clocks_get()
261 clk_put(par->clks[i]); in simplefb_clocks_get()
263 kfree(par->clks); in simplefb_clocks_get()
264 return -EPROBE_DEFER; in simplefb_clocks_get()
266 dev_err(&pdev->dev, "%s: clock %d not found: %ld\n", in simplefb_clocks_get()
270 par->clks[i] = clock; in simplefb_clocks_get()
281 for (i = 0; i < par->clk_count; i++) { in simplefb_clocks_enable()
282 if (par->clks[i]) { in simplefb_clocks_enable()
283 ret = clk_prepare_enable(par->clks[i]); in simplefb_clocks_enable()
285 dev_err(&pdev->dev, in simplefb_clocks_enable()
288 clk_put(par->clks[i]); in simplefb_clocks_enable()
289 par->clks[i] = NULL; in simplefb_clocks_enable()
293 par->clks_enabled = true; in simplefb_clocks_enable()
300 if (!par->clks) in simplefb_clocks_destroy()
303 for (i = 0; i < par->clk_count; i++) { in simplefb_clocks_destroy()
304 if (par->clks[i]) { in simplefb_clocks_destroy()
305 if (par->clks_enabled) in simplefb_clocks_destroy()
306 clk_disable_unprepare(par->clks[i]); in simplefb_clocks_destroy()
307 clk_put(par->clks[i]); in simplefb_clocks_destroy()
311 kfree(par->clks); in simplefb_clocks_destroy()
323 #define SUPPLY_SUFFIX "-supply"
328 * Here we handle the num-supplies and vin*-supply properties of our
329 * "simple-framebuffer" dt node. This is necessary so that we can make sure
347 struct device_node *np = pdev->dev.of_node; in simplefb_regulators_get()
353 if (dev_get_platdata(&pdev->dev) || !np) in simplefb_regulators_get()
358 p = strstr(prop->name, SUPPLY_SUFFIX); in simplefb_regulators_get()
359 if (p && p != prop->name) in simplefb_regulators_get()
366 par->regulators = devm_kcalloc(&pdev->dev, count, in simplefb_regulators_get()
368 if (!par->regulators) in simplefb_regulators_get()
369 return -ENOMEM; in simplefb_regulators_get()
375 p = strstr(prop->name, SUPPLY_SUFFIX); in simplefb_regulators_get()
376 if (!p || p == prop->name) in simplefb_regulators_get()
379 strscpy(name, prop->name, in simplefb_regulators_get()
380 strlen(prop->name) - strlen(SUPPLY_SUFFIX) + 1); in simplefb_regulators_get()
381 regulator = devm_regulator_get_optional(&pdev->dev, name); in simplefb_regulators_get()
383 if (PTR_ERR(regulator) == -EPROBE_DEFER) in simplefb_regulators_get()
384 return -EPROBE_DEFER; in simplefb_regulators_get()
385 dev_err(&pdev->dev, "regulator %s not found: %ld\n", in simplefb_regulators_get()
389 par->regulators[i++] = regulator; in simplefb_regulators_get()
391 par->regulator_count = i; in simplefb_regulators_get()
402 for (i = 0; i < par->regulator_count; i++) { in simplefb_regulators_enable()
403 ret = regulator_enable(par->regulators[i]); in simplefb_regulators_enable()
405 dev_err(&pdev->dev, in simplefb_regulators_enable()
408 devm_regulator_put(par->regulators[i]); in simplefb_regulators_enable()
409 par->regulators[i] = NULL; in simplefb_regulators_enable()
412 par->regulators_enabled = true; in simplefb_regulators_enable()
419 if (!par->regulators || !par->regulators_enabled) in simplefb_regulators_destroy()
422 for (i = 0; i < par->regulator_count; i++) in simplefb_regulators_destroy()
423 if (par->regulators[i]) in simplefb_regulators_destroy()
424 regulator_disable(par->regulators[i]); in simplefb_regulators_destroy()
438 unsigned int i = par->num_genpds; in simplefb_detach_genpds()
440 if (par->num_genpds <= 1) in simplefb_detach_genpds()
443 while (i--) { in simplefb_detach_genpds()
444 if (par->genpd_links[i]) in simplefb_detach_genpds()
445 device_link_del(par->genpd_links[i]); in simplefb_detach_genpds()
447 if (!IS_ERR_OR_NULL(par->genpds[i])) in simplefb_detach_genpds()
448 dev_pm_domain_detach(par->genpds[i], true); in simplefb_detach_genpds()
450 par->num_genpds = 0; in simplefb_detach_genpds()
456 struct device *dev = &pdev->dev; in simplefb_attach_genpds()
460 err = of_count_phandle_with_args(dev->of_node, "power-domains", in simplefb_attach_genpds()
461 "#power-domain-cells"); in simplefb_attach_genpds()
464 if (err == -ENOENT) in simplefb_attach_genpds()
467 dev_err(dev, "failed to parse power-domains: %d\n", err); in simplefb_attach_genpds()
474 * Single power-domain devices are handled by the driver core, so in simplefb_attach_genpds()
478 par->num_genpds = num_genpds; in simplefb_attach_genpds()
482 par->genpds = devm_kcalloc(dev, num_genpds, sizeof(*par->genpds), in simplefb_attach_genpds()
484 if (!par->genpds) in simplefb_attach_genpds()
485 return -ENOMEM; in simplefb_attach_genpds()
487 par->genpd_links = devm_kcalloc(dev, num_genpds, in simplefb_attach_genpds()
488 sizeof(*par->genpd_links), in simplefb_attach_genpds()
490 if (!par->genpd_links) in simplefb_attach_genpds()
491 return -ENOMEM; in simplefb_attach_genpds()
494 * Set par->num_genpds only after genpds and genpd_links are allocated in simplefb_attach_genpds()
498 par->num_genpds = num_genpds; in simplefb_attach_genpds()
500 for (i = 0; i < par->num_genpds; i++) { in simplefb_attach_genpds()
501 par->genpds[i] = dev_pm_domain_attach_by_id(dev, i); in simplefb_attach_genpds()
502 if (IS_ERR(par->genpds[i])) { in simplefb_attach_genpds()
503 err = PTR_ERR(par->genpds[i]); in simplefb_attach_genpds()
504 if (err == -EPROBE_DEFER) { in simplefb_attach_genpds()
513 par->genpd_links[i] = device_link_add(dev, par->genpds[i], in simplefb_attach_genpds()
517 if (!par->genpd_links[i]) in simplefb_attach_genpds()
518 dev_warn(dev, "failed to link power-domain %u\n", i); in simplefb_attach_genpds()
541 return -ENODEV; in simplefb_probe()
543 ret = -ENODEV; in simplefb_probe()
544 if (dev_get_platdata(&pdev->dev)) in simplefb_probe()
546 else if (pdev->dev.of_node) in simplefb_probe()
555 dev_err(&pdev->dev, "No memory resource\n"); in simplefb_probe()
556 return -EINVAL; in simplefb_probe()
562 mem = request_mem_region(res->start, resource_size(res), "simplefb"); in simplefb_probe()
567 * the I/O-memory resource as-is and try to map that instead. in simplefb_probe()
569 dev_warn(&pdev->dev, "simplefb: cannot reserve video memory at %pR\n", res); in simplefb_probe()
573 info = framebuffer_alloc(sizeof(struct simplefb_par), &pdev->dev); in simplefb_probe()
575 ret = -ENOMEM; in simplefb_probe()
580 par = info->par; in simplefb_probe()
582 info->fix = simplefb_fix; in simplefb_probe()
583 info->fix.smem_start = mem->start; in simplefb_probe()
584 info->fix.smem_len = resource_size(mem); in simplefb_probe()
585 info->fix.line_length = params.stride; in simplefb_probe()
587 info->var = simplefb_var; in simplefb_probe()
588 info->var.xres = params.width; in simplefb_probe()
589 info->var.yres = params.height; in simplefb_probe()
590 info->var.xres_virtual = params.width; in simplefb_probe()
591 info->var.yres_virtual = params.height; in simplefb_probe()
592 info->var.bits_per_pixel = params.format->bits_per_pixel; in simplefb_probe()
593 info->var.red = params.format->red; in simplefb_probe()
594 info->var.green = params.format->green; in simplefb_probe()
595 info->var.blue = params.format->blue; in simplefb_probe()
596 info->var.transp = params.format->transp; in simplefb_probe()
598 par->base = info->fix.smem_start; in simplefb_probe()
599 par->size = info->fix.smem_len; in simplefb_probe()
601 info->fbops = &simplefb_ops; in simplefb_probe()
602 info->screen_base = ioremap_wc(info->fix.smem_start, in simplefb_probe()
603 info->fix.smem_len); in simplefb_probe()
604 if (!info->screen_base) { in simplefb_probe()
605 ret = -ENOMEM; in simplefb_probe()
608 info->pseudo_palette = par->palette; in simplefb_probe()
625 dev_info(&pdev->dev, "framebuffer at 0x%lx, 0x%x bytes\n", in simplefb_probe()
626 info->fix.smem_start, info->fix.smem_len); in simplefb_probe()
627 dev_info(&pdev->dev, "format=%s, mode=%dx%dx%d, linelength=%d\n", in simplefb_probe()
628 params.format->name, in simplefb_probe()
629 info->var.xres, info->var.yres, in simplefb_probe()
630 info->var.bits_per_pixel, info->fix.line_length); in simplefb_probe()
633 par->mem = mem; /* release in clean-up handler */ in simplefb_probe()
635 ret = devm_aperture_acquire_for_platform_device(pdev, par->base, par->size); in simplefb_probe()
637 dev_err(&pdev->dev, "Unable to acquire aperture: %d\n", ret); in simplefb_probe()
642 dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret); in simplefb_probe()
646 dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node); in simplefb_probe()
657 iounmap(info->screen_base); in simplefb_probe()
662 release_mem_region(mem->start, resource_size(mem)); in simplefb_probe()
675 { .compatible = "simple-framebuffer", },
682 .name = "simple-framebuffer",
692 MODULE_DESCRIPTION("Simple framebuffer driver");