diff options
Diffstat (limited to 'arch/powerpc/kernel/btext.c')
| -rw-r--r-- | arch/powerpc/kernel/btext.c | 258 | 
1 files changed, 141 insertions, 117 deletions
diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c index 625942ae558..41c011cb607 100644 --- a/arch/powerpc/kernel/btext.c +++ b/arch/powerpc/kernel/btext.c @@ -6,7 +6,7 @@  #include <linux/kernel.h>  #include <linux/string.h>  #include <linux/init.h> -#include <linux/module.h> +#include <linux/export.h>  #include <linux/memblock.h>  #include <asm/sections.h> @@ -25,11 +25,6 @@  static void scrollscreen(void);  #endif -static void draw_byte(unsigned char c, long locX, long locY); -static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb); -static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb); -static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb); -  #define __force_data __attribute__((__section__(".data")))  static int g_loc_X __force_data; @@ -52,6 +47,26 @@ static unsigned char vga_font[cmapsz];  int boot_text_mapped __force_data = 0;  int force_printk_to_btext = 0; +extern void rmci_on(void); +extern void rmci_off(void); + +static inline void rmci_maybe_on(void) +{ +#if defined(CONFIG_PPC_EARLY_DEBUG_BOOTX) && defined(CONFIG_PPC64) +	if (!(mfmsr() & MSR_DR)) +		rmci_on(); +#endif +} + +static inline void rmci_maybe_off(void) +{ +#if defined(CONFIG_PPC_EARLY_DEBUG_BOOTX) && defined(CONFIG_PPC64) +	if (!(mfmsr() & MSR_DR)) +		rmci_off(); +#endif +} + +  #ifdef CONFIG_PPC32  /* Calc BAT values for mapping the display and store them   * in disp_BAT.  Those values are then used from head.S to map @@ -99,7 +114,7 @@ void __init btext_prepare_BAT(void)  /* This function can be used to enable the early boot text when doing   * OF booting or within bootx init. It must be followed by a btext_unmap() - * call before the logical address becomes unuseable + * call before the logical address becomes unusable   */  void __init btext_setup_display(int width, int height, int depth, int pitch,  				unsigned long address) @@ -134,7 +149,7 @@ void __init btext_unmap(void)   *    changes.   */ -static void map_boot_text(void) +void btext_map(void)  {  	unsigned long base, offset, size;  	unsigned char *vbase; @@ -209,7 +224,7 @@ int btext_initialize(struct device_node *np)  	dispDeviceRect[2] = width;  	dispDeviceRect[3] = height; -	map_boot_text(); +	btext_map();  	return 0;  } @@ -283,7 +298,7 @@ void btext_update_display(unsigned long phys, int width, int height,  		iounmap(logicalDisplayBase);  		boot_text_mapped = 0;  	} -	map_boot_text(); +	btext_map();  	g_loc_X = 0;  	g_loc_Y = 0;  	g_max_loc_X = width / 8; @@ -298,6 +313,7 @@ void btext_clearscreen(void)  					(dispDeviceDepth >> 3)) >> 2;  	int i,j; +	rmci_maybe_on();  	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)  	{  		unsigned int *ptr = base; @@ -305,6 +321,7 @@ void btext_clearscreen(void)  			*(ptr++) = 0;  		base += (dispDeviceRowBytes >> 2);  	} +	rmci_maybe_off();  }  void btext_flushscreen(void) @@ -355,6 +372,8 @@ static void scrollscreen(void)  				   (dispDeviceDepth >> 3)) >> 2;  	int i,j; +	rmci_maybe_on(); +  	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)  	{  		unsigned int *src_ptr = src; @@ -371,9 +390,116 @@ static void scrollscreen(void)  			*(dst_ptr++) = 0;  		dst += (dispDeviceRowBytes >> 2);  	} + +	rmci_maybe_off();  }  #endif /* ndef NO_SCROLL */ +static unsigned int expand_bits_8[16] = { +	0x00000000, +	0x000000ff, +	0x0000ff00, +	0x0000ffff, +	0x00ff0000, +	0x00ff00ff, +	0x00ffff00, +	0x00ffffff, +	0xff000000, +	0xff0000ff, +	0xff00ff00, +	0xff00ffff, +	0xffff0000, +	0xffff00ff, +	0xffffff00, +	0xffffffff +}; + +static unsigned int expand_bits_16[4] = { +	0x00000000, +	0x0000ffff, +	0xffff0000, +	0xffffffff +}; + + +static void draw_byte_32(unsigned char *font, unsigned int *base, int rb) +{ +	int l, bits; +	int fg = 0xFFFFFFFFUL; +	int bg = 0x00000000UL; + +	for (l = 0; l < 16; ++l) +	{ +		bits = *font++; +		base[0] = (-(bits >> 7) & fg) ^ bg; +		base[1] = (-((bits >> 6) & 1) & fg) ^ bg; +		base[2] = (-((bits >> 5) & 1) & fg) ^ bg; +		base[3] = (-((bits >> 4) & 1) & fg) ^ bg; +		base[4] = (-((bits >> 3) & 1) & fg) ^ bg; +		base[5] = (-((bits >> 2) & 1) & fg) ^ bg; +		base[6] = (-((bits >> 1) & 1) & fg) ^ bg; +		base[7] = (-(bits & 1) & fg) ^ bg; +		base = (unsigned int *) ((char *)base + rb); +	} +} + +static inline void draw_byte_16(unsigned char *font, unsigned int *base, int rb) +{ +	int l, bits; +	int fg = 0xFFFFFFFFUL; +	int bg = 0x00000000UL; +	unsigned int *eb = (int *)expand_bits_16; + +	for (l = 0; l < 16; ++l) +	{ +		bits = *font++; +		base[0] = (eb[bits >> 6] & fg) ^ bg; +		base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg; +		base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg; +		base[3] = (eb[bits & 3] & fg) ^ bg; +		base = (unsigned int *) ((char *)base + rb); +	} +} + +static inline void draw_byte_8(unsigned char *font, unsigned int *base, int rb) +{ +	int l, bits; +	int fg = 0x0F0F0F0FUL; +	int bg = 0x00000000UL; +	unsigned int *eb = (int *)expand_bits_8; + +	for (l = 0; l < 16; ++l) +	{ +		bits = *font++; +		base[0] = (eb[bits >> 4] & fg) ^ bg; +		base[1] = (eb[bits & 0xf] & fg) ^ bg; +		base = (unsigned int *) ((char *)base + rb); +	} +} + +static noinline void draw_byte(unsigned char c, long locX, long locY) +{ +	unsigned char *base	= calc_base(locX << 3, locY << 4); +	unsigned char *font	= &vga_font[((unsigned int)c) * 16]; +	int rb			= dispDeviceRowBytes; + +	rmci_maybe_on(); +	switch(dispDeviceDepth) { +	case 24: +	case 32: +		draw_byte_32(font, (unsigned int *)base, rb); +		break; +	case 15: +	case 16: +		draw_byte_16(font, (unsigned int *)base, rb); +		break; +	case 8: +		draw_byte_8(font, (unsigned int *)base, rb); +		break; +	} +	rmci_maybe_off(); +} +  void btext_drawchar(char c)  {  	int cline = 0; @@ -465,107 +591,12 @@ void btext_drawhex(unsigned long v)  	btext_drawchar(' ');  } -static void draw_byte(unsigned char c, long locX, long locY) -{ -	unsigned char *base	= calc_base(locX << 3, locY << 4); -	unsigned char *font	= &vga_font[((unsigned int)c) * 16]; -	int rb			= dispDeviceRowBytes; - -	switch(dispDeviceDepth) { -	case 24: -	case 32: -		draw_byte_32(font, (unsigned int *)base, rb); -		break; -	case 15: -	case 16: -		draw_byte_16(font, (unsigned int *)base, rb); -		break; -	case 8: -		draw_byte_8(font, (unsigned int *)base, rb); -		break; -	} -} - -static unsigned int expand_bits_8[16] = { -	0x00000000, -	0x000000ff, -	0x0000ff00, -	0x0000ffff, -	0x00ff0000, -	0x00ff00ff, -	0x00ffff00, -	0x00ffffff, -	0xff000000, -	0xff0000ff, -	0xff00ff00, -	0xff00ffff, -	0xffff0000, -	0xffff00ff, -	0xffffff00, -	0xffffffff -}; - -static unsigned int expand_bits_16[4] = { -	0x00000000, -	0x0000ffff, -	0xffff0000, -	0xffffffff -}; - - -static void draw_byte_32(unsigned char *font, unsigned int *base, int rb) -{ -	int l, bits; -	int fg = 0xFFFFFFFFUL; -	int bg = 0x00000000UL; - -	for (l = 0; l < 16; ++l) -	{ -		bits = *font++; -		base[0] = (-(bits >> 7) & fg) ^ bg; -		base[1] = (-((bits >> 6) & 1) & fg) ^ bg; -		base[2] = (-((bits >> 5) & 1) & fg) ^ bg; -		base[3] = (-((bits >> 4) & 1) & fg) ^ bg; -		base[4] = (-((bits >> 3) & 1) & fg) ^ bg; -		base[5] = (-((bits >> 2) & 1) & fg) ^ bg; -		base[6] = (-((bits >> 1) & 1) & fg) ^ bg; -		base[7] = (-(bits & 1) & fg) ^ bg; -		base = (unsigned int *) ((char *)base + rb); -	} -} - -static void draw_byte_16(unsigned char *font, unsigned int *base, int rb) -{ -	int l, bits; -	int fg = 0xFFFFFFFFUL; -	int bg = 0x00000000UL; -	unsigned int *eb = (int *)expand_bits_16; - -	for (l = 0; l < 16; ++l) -	{ -		bits = *font++; -		base[0] = (eb[bits >> 6] & fg) ^ bg; -		base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg; -		base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg; -		base[3] = (eb[bits & 3] & fg) ^ bg; -		base = (unsigned int *) ((char *)base + rb); -	} -} - -static void draw_byte_8(unsigned char *font, unsigned int *base, int rb) +void __init udbg_init_btext(void)  { -	int l, bits; -	int fg = 0x0F0F0F0FUL; -	int bg = 0x00000000UL; -	unsigned int *eb = (int *)expand_bits_8; - -	for (l = 0; l < 16; ++l) -	{ -		bits = *font++; -		base[0] = (eb[bits >> 4] & fg) ^ bg; -		base[1] = (eb[bits & 0xf] & fg) ^ bg; -		base = (unsigned int *) ((char *)base + rb); -	} +	/* If btext is enabled, we might have a BAT setup for early display, +	 * thus we do enable some very basic udbg output +	 */ +	udbg_putc = btext_drawchar;  }  static unsigned char vga_font[cmapsz] = { @@ -913,10 +944,3 @@ static unsigned char vga_font[cmapsz] = {  0x00, 0x00, 0x00, 0x00,  }; -void __init udbg_init_btext(void) -{ -	/* If btext is enabled, we might have a BAT setup for early display, -	 * thus we do enable some very basic udbg output -	 */ -	udbg_putc = btext_drawchar; -}  | 
