Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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 probing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Try to convert "screen_info" into a "simple-framebuffer" compatible mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * If the mode is incompatible, we return "false" and let the caller create
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * legacy nodes instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/platform_data/simplefb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/screen_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <asm/sysfb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) static const char simplefb_resname[] = "BOOTFB";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) static const struct simplefb_format formats[] = SIMPLEFB_FORMATS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) /* try parsing x86 screen_info into a simple-framebuffer mode struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) __init bool parse_mode(const struct screen_info *si,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 		       struct simplefb_platform_data *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	const struct simplefb_format *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	__u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	type = si->orig_video_isVGA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	if (type != VIDEO_TYPE_VLFB && type != VIDEO_TYPE_EFI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	for (i = 0; i < ARRAY_SIZE(formats); ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 		f = &formats[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		if (si->lfb_depth == f->bits_per_pixel &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		    si->red_size == f->red.length &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		    si->red_pos == f->red.offset &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		    si->green_size == f->green.length &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		    si->green_pos == f->green.offset &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		    si->blue_size == f->blue.length &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		    si->blue_pos == f->blue.offset &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		    si->rsvd_size == f->transp.length &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		    si->rsvd_pos == f->transp.offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 			mode->format = f->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 			mode->width = si->lfb_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 			mode->height = si->lfb_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 			mode->stride = si->lfb_linelength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 			return true;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) __init int create_simplefb(const struct screen_info *si,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 			   const struct simplefb_platform_data *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	struct platform_device *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	struct resource res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	u64 base, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	u32 length;
^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) 	 * If the 64BIT_BASE capability is set, ext_lfb_base will contain the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	 * upper half of the base address. Assemble the address, then make sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	 * it is valid and we can actually access it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	base = si->lfb_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	if (si->capabilities & VIDEO_CAPABILITY_64BIT_BASE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		base |= (u64)si->ext_lfb_base << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	if (!base || (u64)(resource_size_t)base != base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		printk(KERN_DEBUG "sysfb: inaccessible VRAM base\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	 * Don't use lfb_size as IORESOURCE size, since it may contain the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	 * entire VMEM, and thus require huge mappings. Use just the part we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	 * need, that is, the part where the framebuffer is located. But verify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	 * that it does not exceed the advertised VMEM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	 * Note that in case of VBE, the lfb_size is shifted by 16 bits for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	 * historical reasons.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	size = si->lfb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	if (si->orig_video_isVGA == VIDEO_TYPE_VLFB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		size <<= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	length = mode->height * mode->stride;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	if (length > size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		printk(KERN_WARNING "sysfb: VRAM smaller than advertised\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	length = PAGE_ALIGN(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	/* setup IORESOURCE_MEM as framebuffer memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	memset(&res, 0, sizeof(res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	res.name = simplefb_resname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	res.start = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	res.end = res.start + length - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	if (res.end <= res.start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	pd = platform_device_register_resndata(NULL, "simple-framebuffer", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 					       &res, 1, mode, sizeof(*mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	return PTR_ERR_OR_ZERO(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }