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-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* -*- linux-c -*- ------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *   Copyright (C) 1991, 1992 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *   Copyright 2007-2008 rPath, Inc. - All Rights Reserved
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * arch/i386/boot/video-mode.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * Set the video mode.  This is separated out into a different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * file in order to be shared with the ACPI wakeup code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "boot.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "video.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "vesa.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <uapi/asm/boot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * Common variables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) int adapter;		/* 0=CGA/MDA/HGC, 1=EGA, 2=VGA+ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) int force_x, force_y;	/* Don't query the BIOS for cols/rows */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) int do_restore;		/* Screen contents changed during mode flip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) int graphic_mode;	/* Graphic mode with linear frame buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) /* Probe the video drivers and have them generate their mode lists. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) void probe_cards(int unsafe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	struct card_info *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	static u8 probed[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	if (probed[unsafe])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	probed[unsafe] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	for (card = video_cards; card < video_cards_end; card++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		if (card->unsafe == unsafe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 			if (card->probe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 				card->nmodes = card->probe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 				card->nmodes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) /* Test if a mode is defined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) int mode_defined(u16 mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	struct card_info *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	struct mode_info *mi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	for (card = video_cards; card < video_cards_end; card++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		mi = card->modes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		for (i = 0; i < card->nmodes; i++, mi++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 			if (mi->mode == mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 				return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	return 0;
^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) /* Set mode (without recalc) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) static int raw_set_mode(u16 mode, u16 *real_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	int nmode, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	struct card_info *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	struct mode_info *mi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	/* Drop the recalc bit if set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	mode &= ~VIDEO_RECALC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	/* Scan for mode based on fixed ID, position, or resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	nmode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	for (card = video_cards; card < video_cards_end; card++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		mi = card->modes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		for (i = 0; i < card->nmodes; i++, mi++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			int visible = mi->x || mi->y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 			if ((mode == nmode && visible) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 			    mode == mi->mode ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			    mode == (mi->y << 8)+mi->x) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 				*real_mode = mi->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 				return card->set_mode(mi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			if (visible)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 				nmode++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	/* Nothing found?  Is it an "exceptional" (unprobed) mode? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	for (card = video_cards; card < video_cards_end; card++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		if (mode >= card->xmode_first &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		    mode < card->xmode_first+card->xmode_n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			struct mode_info mix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			*real_mode = mix.mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			mix.x = mix.y = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			return card->set_mode(&mix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	/* Otherwise, failure... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  * Recalculate the vertical video cutoff (hack!)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static void vga_recalc_vertical(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	unsigned int font_size, rows;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	u16 crtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	u8 pt, ov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	set_fs(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	font_size = rdfs8(0x485); /* BIOS: font size (pixels) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	rows = force_y ? force_y : rdfs8(0x484)+1; /* Text rows */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	rows *= font_size;	/* Visible scan lines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	rows--;			/* ... minus one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	crtc = vga_crtc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	pt = in_idx(crtc, 0x11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	pt &= ~0x80;		/* Unlock CR0-7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	out_idx(pt, crtc, 0x11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	out_idx((u8)rows, crtc, 0x12); /* Lower height register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	ov = in_idx(crtc, 0x07); /* Overflow register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	ov &= 0xbd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	ov |= (rows >> (8-1)) & 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	ov |= (rows >> (9-6)) & 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	out_idx(ov, crtc, 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* Set mode (with recalc if specified) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) int set_mode(u16 mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	u16 real_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	/* Very special mode numbers... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	if (mode == VIDEO_CURRENT_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		return 0;	/* Nothing to do... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	else if (mode == NORMAL_VGA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		mode = VIDEO_80x25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	else if (mode == EXTENDED_VGA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		mode = VIDEO_8POINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	rv = raw_set_mode(mode, &real_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	if (rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	if (mode & VIDEO_RECALC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		vga_recalc_vertical();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	/* Save the canonical mode number for the kernel, not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	   an alias, size specification or menu position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #ifndef _WAKEUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	boot_params.hdr.vid_mode = real_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }