Lines Matching +full:simple +full:- +full:framebuffer
1 // SPDX-License-Identifier: GPL-2.0-only
33 #define DRIVER_DESC "DRM driver for simple-framebuffer platform devices"
46 drm_err(dev, "simplefb: invalid framebuffer %s of %u\n", in simplefb_get_validated_int()
48 return -EINVAL; in simplefb_get_validated_int()
58 drm_err(dev, "simplefb: invalid framebuffer %s of %u\n", in simplefb_get_validated_int0()
60 return -EINVAL; in simplefb_get_validated_int0()
74 drm_err(dev, "simplefb: missing framebuffer format\n"); in simplefb_get_validated_format()
75 return ERR_PTR(-EINVAL); in simplefb_get_validated_format()
79 if (!strcmp(format_name, fmt->name)) { in simplefb_get_validated_format()
80 info = drm_format_info(fmt->fourcc); in simplefb_get_validated_format()
82 return ERR_PTR(-EINVAL); in simplefb_get_validated_format()
88 drm_err(dev, "simplefb: unknown framebuffer format %s\n", in simplefb_get_validated_format()
91 return ERR_PTR(-EINVAL); in simplefb_get_validated_format()
98 return simplefb_get_validated_int0(dev, "width", pd->width); in simplefb_get_width_pd()
105 return simplefb_get_validated_int0(dev, "height", pd->height); in simplefb_get_height_pd()
112 return simplefb_get_validated_int(dev, "stride", pd->stride); in simplefb_get_stride_pd()
119 return simplefb_get_validated_format(dev, pd->format); in simplefb_get_format_pd()
129 drm_err(dev, "simplefb: cannot parse framebuffer %s: error %d\n", in simplefb_read_u32_of()
141 drm_err(dev, "simplefb: cannot parse framebuffer %s: error %d\n", in simplefb_read_string_of()
197 np = of_parse_phandle(of_node, "memory-region", 0); in simplefb_get_memory_of()
201 res = devm_kzalloc(dev->dev, sizeof(*res), GFP_KERNEL); in simplefb_get_memory_of()
203 return ERR_PTR(-ENOMEM); in simplefb_get_memory_of()
210 drm_warn(dev, "preferring \"memory-region\" over \"reg\" property\n"); in simplefb_get_memory_of()
216 * Simple Framebuffer device
232 /* power-domains */
269 * Here we handle the clocks property of our "simple-framebuffer" dt node.
290 for (i = 0; i < sdev->clk_count; ++i) { in simpledrm_device_release_clocks()
291 if (sdev->clks[i]) { in simpledrm_device_release_clocks()
292 clk_disable_unprepare(sdev->clks[i]); in simpledrm_device_release_clocks()
293 clk_put(sdev->clks[i]); in simpledrm_device_release_clocks()
300 struct drm_device *dev = &sdev->dev; in simpledrm_device_init_clocks()
301 struct platform_device *pdev = to_platform_device(dev->dev); in simpledrm_device_init_clocks()
302 struct device_node *of_node = pdev->dev.of_node; in simpledrm_device_init_clocks()
307 if (dev_get_platdata(&pdev->dev) || !of_node) in simpledrm_device_init_clocks()
310 sdev->clk_count = of_clk_get_parent_count(of_node); in simpledrm_device_init_clocks()
311 if (!sdev->clk_count) in simpledrm_device_init_clocks()
314 sdev->clks = drmm_kzalloc(dev, sdev->clk_count * sizeof(sdev->clks[0]), in simpledrm_device_init_clocks()
316 if (!sdev->clks) in simpledrm_device_init_clocks()
317 return -ENOMEM; in simpledrm_device_init_clocks()
319 for (i = 0; i < sdev->clk_count; ++i) { in simpledrm_device_init_clocks()
323 if (ret == -EPROBE_DEFER) in simpledrm_device_init_clocks()
335 sdev->clks[i] = clock; in simpledrm_device_init_clocks()
338 return devm_add_action_or_reset(&pdev->dev, in simpledrm_device_init_clocks()
344 --i; in simpledrm_device_init_clocks()
345 if (sdev->clks[i]) { in simpledrm_device_init_clocks()
346 clk_disable_unprepare(sdev->clks[i]); in simpledrm_device_init_clocks()
347 clk_put(sdev->clks[i]); in simpledrm_device_init_clocks()
361 #define SUPPLY_SUFFIX "-supply"
366 * Here we handle the num-supplies and vin*-supply properties of our
367 * "simple-framebuffer" dt node. This is necessary so that we can make sure
388 for (i = 0; i < sdev->regulator_count; ++i) { in simpledrm_device_release_regulators()
389 if (sdev->regulators[i]) { in simpledrm_device_release_regulators()
390 regulator_disable(sdev->regulators[i]); in simpledrm_device_release_regulators()
391 regulator_put(sdev->regulators[i]); in simpledrm_device_release_regulators()
398 struct drm_device *dev = &sdev->dev; in simpledrm_device_init_regulators()
399 struct platform_device *pdev = to_platform_device(dev->dev); in simpledrm_device_init_regulators()
400 struct device_node *of_node = pdev->dev.of_node; in simpledrm_device_init_regulators()
407 if (dev_get_platdata(&pdev->dev) || !of_node) in simpledrm_device_init_regulators()
412 p = strstr(prop->name, SUPPLY_SUFFIX); in simpledrm_device_init_regulators()
413 if (p && p != prop->name) in simpledrm_device_init_regulators()
420 sdev->regulators = drmm_kzalloc(dev, in simpledrm_device_init_regulators()
421 count * sizeof(sdev->regulators[0]), in simpledrm_device_init_regulators()
423 if (!sdev->regulators) in simpledrm_device_init_regulators()
424 return -ENOMEM; in simpledrm_device_init_regulators()
430 p = strstr(prop->name, SUPPLY_SUFFIX); in simpledrm_device_init_regulators()
431 if (!p || p == prop->name) in simpledrm_device_init_regulators()
433 len = strlen(prop->name) - strlen(SUPPLY_SUFFIX) + 1; in simpledrm_device_init_regulators()
434 strscpy(name, prop->name, min(sizeof(name), len)); in simpledrm_device_init_regulators()
436 regulator = regulator_get_optional(&pdev->dev, name); in simpledrm_device_init_regulators()
439 if (ret == -EPROBE_DEFER) in simpledrm_device_init_regulators()
454 sdev->regulators[i++] = regulator; in simpledrm_device_init_regulators()
456 sdev->regulator_count = i; in simpledrm_device_init_regulators()
458 return devm_add_action_or_reset(&pdev->dev, in simpledrm_device_init_regulators()
464 --i; in simpledrm_device_init_regulators()
465 if (sdev->regulators[i]) { in simpledrm_device_init_regulators()
466 regulator_disable(sdev->regulators[i]); in simpledrm_device_init_regulators()
467 regulator_put(sdev->regulators[i]); in simpledrm_device_init_regulators()
483 * Here we handle the power-domains properties of our "simple-framebuffer"
484 * dt node. This is only necessary if there is more than one power-domain.
485 * A single power-domains is handled automatically by the driver core. Multiple
486 * power-domains have to be handled by drivers since the driver core can't know
491 * When the driver unloads, we detach from the power-domains.
495 * up the "simple-framebuffer" dt node, and the PM domain providers in the
506 if (sdev->pwr_dom_count <= 1) in simpledrm_device_detach_genpd()
509 for (i = sdev->pwr_dom_count - 1; i >= 0; i--) { in simpledrm_device_detach_genpd()
510 if (sdev->pwr_dom_links[i]) in simpledrm_device_detach_genpd()
511 device_link_del(sdev->pwr_dom_links[i]); in simpledrm_device_detach_genpd()
512 if (!IS_ERR_OR_NULL(sdev->pwr_dom_devs[i])) in simpledrm_device_detach_genpd()
513 dev_pm_domain_detach(sdev->pwr_dom_devs[i], true); in simpledrm_device_detach_genpd()
519 struct device *dev = sdev->dev.dev; in simpledrm_device_attach_genpd()
522 sdev->pwr_dom_count = of_count_phandle_with_args(dev->of_node, "power-domains", in simpledrm_device_attach_genpd()
523 "#power-domain-cells"); in simpledrm_device_attach_genpd()
525 * Single power-domain devices are handled by driver core nothing to do in simpledrm_device_attach_genpd()
526 * here. The same for device nodes without "power-domains" property. in simpledrm_device_attach_genpd()
528 if (sdev->pwr_dom_count <= 1) in simpledrm_device_attach_genpd()
531 sdev->pwr_dom_devs = devm_kcalloc(dev, sdev->pwr_dom_count, in simpledrm_device_attach_genpd()
532 sizeof(*sdev->pwr_dom_devs), in simpledrm_device_attach_genpd()
534 if (!sdev->pwr_dom_devs) in simpledrm_device_attach_genpd()
535 return -ENOMEM; in simpledrm_device_attach_genpd()
537 sdev->pwr_dom_links = devm_kcalloc(dev, sdev->pwr_dom_count, in simpledrm_device_attach_genpd()
538 sizeof(*sdev->pwr_dom_links), in simpledrm_device_attach_genpd()
540 if (!sdev->pwr_dom_links) in simpledrm_device_attach_genpd()
541 return -ENOMEM; in simpledrm_device_attach_genpd()
543 for (i = 0; i < sdev->pwr_dom_count; i++) { in simpledrm_device_attach_genpd()
544 sdev->pwr_dom_devs[i] = dev_pm_domain_attach_by_id(dev, i); in simpledrm_device_attach_genpd()
545 if (IS_ERR(sdev->pwr_dom_devs[i])) { in simpledrm_device_attach_genpd()
546 int ret = PTR_ERR(sdev->pwr_dom_devs[i]); in simpledrm_device_attach_genpd()
547 if (ret == -EPROBE_DEFER) { in simpledrm_device_attach_genpd()
551 drm_warn(&sdev->dev, in simpledrm_device_attach_genpd()
556 sdev->pwr_dom_links[i] = device_link_add(dev, in simpledrm_device_attach_genpd()
557 sdev->pwr_dom_devs[i], in simpledrm_device_attach_genpd()
561 if (!sdev->pwr_dom_links[i]) in simpledrm_device_attach_genpd()
562 drm_warn(&sdev->dev, "failed to link power-domain %d\n", i); in simpledrm_device_attach_genpd()
589 struct drm_framebuffer *new_fb = new_plane_state->fb; in simpledrm_primary_plane_helper_atomic_check()
590 struct drm_crtc *new_crtc = new_plane_state->crtc; in simpledrm_primary_plane_helper_atomic_check()
592 struct drm_device *dev = plane->dev; in simpledrm_primary_plane_helper_atomic_check()
605 else if (!new_plane_state->visible) in simpledrm_primary_plane_helper_atomic_check()
608 if (new_fb->format != sdev->format) { in simpledrm_primary_plane_helper_atomic_check()
612 buf = drm_format_conv_state_reserve(&new_shadow_plane_state->fmtcnv_state, in simpledrm_primary_plane_helper_atomic_check()
613 sdev->pitch, GFP_KERNEL); in simpledrm_primary_plane_helper_atomic_check()
615 return -ENOMEM; in simpledrm_primary_plane_helper_atomic_check()
627 struct drm_framebuffer *fb = plane_state->fb; in simpledrm_primary_plane_helper_atomic_update()
628 struct drm_device *dev = plane->dev; in simpledrm_primary_plane_helper_atomic_update()
643 struct drm_rect dst_clip = plane_state->dst; in simpledrm_primary_plane_helper_atomic_update()
644 struct iosys_map dst = sdev->screen_base; in simpledrm_primary_plane_helper_atomic_update()
649 iosys_map_incr(&dst, drm_fb_clip_offset(sdev->pitch, sdev->format, &dst_clip)); in simpledrm_primary_plane_helper_atomic_update()
650 drm_fb_blit(&dst, &sdev->pitch, sdev->format->format, shadow_plane_state->data, in simpledrm_primary_plane_helper_atomic_update()
651 fb, &damage, &shadow_plane_state->fmtcnv_state); in simpledrm_primary_plane_helper_atomic_update()
662 struct drm_device *dev = plane->dev; in simpledrm_primary_plane_helper_atomic_disable()
670 iosys_map_memset(&sdev->screen_base, 0, 0, sdev->pitch * sdev->mode.vdisplay); in simpledrm_primary_plane_helper_atomic_disable()
678 struct simpledrm_device *sdev = simpledrm_device_of_dev(plane->dev); in simpledrm_primary_plane_helper_get_scanout_buffer()
680 sb->width = sdev->mode.hdisplay; in simpledrm_primary_plane_helper_get_scanout_buffer()
681 sb->height = sdev->mode.vdisplay; in simpledrm_primary_plane_helper_get_scanout_buffer()
682 sb->format = sdev->format; in simpledrm_primary_plane_helper_get_scanout_buffer()
683 sb->pitch[0] = sdev->pitch; in simpledrm_primary_plane_helper_get_scanout_buffer()
684 sb->map[0] = sdev->screen_base; in simpledrm_primary_plane_helper_get_scanout_buffer()
707 struct simpledrm_device *sdev = simpledrm_device_of_dev(crtc->dev); in simpledrm_crtc_helper_mode_valid()
709 return drm_crtc_helper_mode_valid_fixed(crtc, mode, &sdev->mode); in simpledrm_crtc_helper_mode_valid()
737 struct simpledrm_device *sdev = simpledrm_device_of_dev(connector->dev); in simpledrm_connector_helper_get_modes()
739 return drm_connector_helper_get_modes_fixed(connector, &sdev->mode); in simpledrm_connector_helper_get_modes()
779 const struct simplefb_platform_data *pd = dev_get_platdata(&pdev->dev); in simpledrm_device_create()
780 struct device_node *of_node = pdev->dev.of_node; in simpledrm_device_create()
796 sdev = devm_drm_dev_alloc(&pdev->dev, drv, struct simpledrm_device, dev); in simpledrm_device_create()
799 dev = &sdev->dev; in simpledrm_device_create()
847 simplefb_read_u32_of(dev, panel_node, "width-mm", &width_mm); in simpledrm_device_create()
848 simplefb_read_u32_of(dev, panel_node, "height-mm", &height_mm); in simpledrm_device_create()
853 return ERR_PTR(-ENODEV); in simpledrm_device_create()
858 return ERR_PTR(-EINVAL); in simpledrm_device_create()
870 sdev->mode = simpledrm_mode(width, height, width_mm, height_mm); in simpledrm_device_create()
871 sdev->format = format; in simpledrm_device_create()
872 sdev->pitch = stride; in simpledrm_device_create()
874 drm_dbg(dev, "display mode={" DRM_MODE_FMT "}\n", DRM_MODE_ARG(&sdev->mode)); in simpledrm_device_create()
875 drm_dbg(dev, "framebuffer format=%p4cc, size=%dx%d, stride=%d byte\n", in simpledrm_device_create()
876 &format->format, width, height, stride); in simpledrm_device_create()
885 ret = devm_aperture_acquire_for_platform_device(pdev, mem->start, in simpledrm_device_create()
892 drm_dbg(dev, "using system memory framebuffer at %pr\n", mem); in simpledrm_device_create()
894 screen_base = devm_memremap(dev->dev, mem->start, resource_size(mem), MEMREMAP_WC); in simpledrm_device_create()
898 iosys_map_set_vaddr(&sdev->screen_base, screen_base); in simpledrm_device_create()
904 return ERR_PTR(-EINVAL); in simpledrm_device_create()
906 ret = devm_aperture_acquire_for_platform_device(pdev, res->start, in simpledrm_device_create()
913 drm_dbg(dev, "using I/O memory framebuffer at %pr\n", res); in simpledrm_device_create()
915 mem = devm_request_mem_region(&pdev->dev, res->start, resource_size(res), in simpledrm_device_create()
916 drv->name); in simpledrm_device_create()
921 * the I/O-memory resource as-is and try to map that instead. in simpledrm_device_create()
927 screen_base = devm_ioremap_wc(&pdev->dev, mem->start, resource_size(mem)); in simpledrm_device_create()
929 return ERR_PTR(-ENOMEM); in simpledrm_device_create()
931 iosys_map_set_vaddr_iomem(&sdev->screen_base, screen_base); in simpledrm_device_create()
945 dev->mode_config.min_width = width; in simpledrm_device_create()
946 dev->mode_config.max_width = max_width; in simpledrm_device_create()
947 dev->mode_config.min_height = height; in simpledrm_device_create()
948 dev->mode_config.max_height = max_height; in simpledrm_device_create()
949 dev->mode_config.preferred_depth = format->depth; in simpledrm_device_create()
950 dev->mode_config.funcs = &simpledrm_mode_config_funcs; in simpledrm_device_create()
954 nformats = drm_fb_build_fourcc_list(dev, &format->format, 1, in simpledrm_device_create()
955 sdev->formats, ARRAY_SIZE(sdev->formats)); in simpledrm_device_create()
957 primary_plane = &sdev->primary_plane; in simpledrm_device_create()
959 sdev->formats, nformats, in simpledrm_device_create()
969 crtc = &sdev->crtc; in simpledrm_device_create()
978 encoder = &sdev->encoder; in simpledrm_device_create()
983 encoder->possible_crtcs = drm_crtc_mask(crtc); in simpledrm_device_create()
987 connector = &sdev->connector; in simpledrm_device_create()
1036 dev = &sdev->dev; in simpledrm_probe()
1042 drm_client_setup(dev, sdev->format); in simpledrm_probe()
1050 struct drm_device *dev = &sdev->dev; in simpledrm_remove()
1056 { .compatible = "simple-framebuffer", },
1063 .name = "simple-framebuffer", /* connect to sysfb */