^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Generic System Framebuffers on x86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Simple-Framebuffer support for x86 systems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Create a platform-device for any available boot framebuffer. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * simple-framebuffer platform device is already available on DT systems, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * this module parses the global "screen_info" object and creates a suitable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * platform device compatible with the "simple-framebuffer" DT object. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * the framebuffer is incompatible, we instead create a legacy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * "vesa-framebuffer", "efi-framebuffer" or "platform-framebuffer" device and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * pass the screen_info as platform_data. This allows legacy drivers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * to pick these devices up without messing with simple-framebuffer drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * The global "screen_info" is still valid at all times.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * If CONFIG_X86_SYSFB is not selected, we never register "simple-framebuffer"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * platform devices, but only use legacy framebuffer devices for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * backwards compatibility.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * TODO: We set the dev_id field of all platform-devices to 0. This allows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * other x86 OF/DT parsers to create such devices, too. However, they must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * start at offset 1 for this to work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/platform_data/simplefb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/screen_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <asm/sysfb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static __init int sysfb_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct screen_info *si = &screen_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct simplefb_platform_data mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct platform_device *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) bool compatible;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) sysfb_apply_efi_quirks();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* try to create a simple-framebuffer device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) compatible = parse_mode(si, &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (compatible) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ret = create_simplefb(si, &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* if the FB is incompatible, create a legacy framebuffer device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (si->orig_video_isVGA == VIDEO_TYPE_EFI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) name = "efi-framebuffer";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) else if (si->orig_video_isVGA == VIDEO_TYPE_VLFB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) name = "vesa-framebuffer";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) name = "platform-framebuffer";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) pd = platform_device_register_resndata(NULL, name, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) NULL, 0, si, sizeof(*si));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return PTR_ERR_OR_ZERO(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* must execute after PCI subsystem for EFI quirks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) device_initcall(sysfb_init);