// SPDX-License-Identifier: GPL-2.0
/*
 * Procedures for drawing on the screen early on in the boot process.
 *
 * Benjamin Herrenschmidt <benh@kernel.crashing.org>
 */
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/hex.h>
#include <linux/init.h>
#include <linux/export.h>
#include <linux/font.h>
#include <linux/memblock.h>
#include <linux/pgtable.h>
#include <linux/of.h>

#include <asm/sections.h>
#include <asm/btext.h>
#include <asm/page.h>
#include <asm/mmu.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/udbg.h>
#include <asm/setup.h>

#define NO_SCROLL

#ifndef NO_SCROLL
static void scrollscreen(void);
#endif

#define __force_data __section(".data")

static int g_loc_X __force_data;
static int g_loc_Y __force_data;
static int g_max_loc_X __force_data;
static int g_max_loc_Y __force_data;

static int dispDeviceRowBytes __force_data;
static int dispDeviceDepth  __force_data;
static int dispDeviceRect[4] __force_data;
static unsigned char *dispDeviceBase __force_data;
static unsigned char *logicalDisplayBase __force_data;

unsigned long disp_BAT[2] __initdata = {0, 0};

static int boot_text_mapped __force_data;

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
 * the display during identify_machine() and MMU_Init()
 *
 * The display is mapped to virtual address 0xD0000000, rather
 * than 1:1, because some CHRP machines put the frame buffer
 * in the region starting at 0xC0000000 (PAGE_OFFSET).
 * This mapping is temporary and will disappear as soon as the
 * setup done by MMU_Init() is applied.
 *
 * For now, we align the BAT and then map 8Mb on 601 and 16Mb
 * on other PPCs. This may cause trouble if the framebuffer
 * is really badly aligned, but I didn't encounter this case
 * yet.
 */
void __init btext_prepare_BAT(void)
{
	unsigned long vaddr = PAGE_OFFSET + 0x10000000;
	unsigned long addr;
	unsigned long lowbits;

	addr = (unsigned long)dispDeviceBase;
	if (!addr) {
		boot_text_mapped = 0;
		return;
	}
	lowbits = addr & ~0xFF000000UL;
	addr &= 0xFF000000UL;
	disp_BAT[0] = vaddr | (BL_16M<<2) | 2;
	disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);
	logicalDisplayBase = (void *) (vaddr + lowbits);
}
#endif


/* 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 unusable
 */
void __init btext_setup_display(int width, int height, int depth, int pitch,
				unsigned long address)
{
	g_loc_X = 0;
	g_loc_Y = 0;
	g_max_loc_X = width / 8;
	g_max_loc_Y = height / 16;
	logicalDisplayBase = (unsigned char *)address;
	dispDeviceBase = (unsigned char *)address;
	dispDeviceRowBytes = pitch;
	dispDeviceDepth = depth == 15 ? 16 : depth;
	dispDeviceRect[0] = dispDeviceRect[1] = 0;
	dispDeviceRect[2] = width;
	dispDeviceRect[3] = height;
	boot_text_mapped = 1;
}

void __init btext_unmap(void)
{
	boot_text_mapped = 0;
}

/* Here's a small text engine to use during early boot
 * or for debugging purposes
 *
 * todo:
 *
 *  - build some kind of vgacon with it to enable early printk
 *  - move to a separate file
 *  - add a few video driver hooks to keep in sync with display
 *    changes.
 */

void btext_map(void)
{
	unsigned long base, offset, size;
	unsigned char *vbase;

	/* By default, we are no longer mapped */
	boot_text_mapped = 0;
	if (!dispDeviceBase)
		return;
	base = ((unsigned long) dispDeviceBase) & 0xFFFFF000UL;
	offset = ((unsigned long) dispDeviceBase) - base;
	size = dispDeviceRowBytes * dispDeviceRect[3] + offset
		+ dispDeviceRect[0];
	vbase = ioremap_wc(base, size);
	if (!vbase)
		return;
	logicalDisplayBase = vbase + offset;
	boot_text_mapped = 1;
}

static int __init btext_initialize(struct device_node *np)
{
	unsigned int width, height, depth, pitch;
	unsigned long address = 0;
	const u32 *prop;

	prop = of_get_property(np, "linux,bootx-width", NULL);
	if (prop == NULL)
		prop = of_get_property(np, "width", NULL);
	if (prop == NULL)
		return -EINVAL;
	width = *prop;
	prop = of_get_property(np, "linux,bootx-height", NULL);
	if (prop == NULL)
		prop = of_get_property(np, "height", NULL);
	if (prop == NULL)
		return -EINVAL;
	height = *prop;
	prop = of_get_property(np, "linux,bootx-depth", NULL);
	if (prop == NULL)
		prop = of_get_property(np, "depth", NULL);
	if (prop == NULL)
		return -EINVAL;
	depth = *prop;
	pitch = width * ((depth + 7) / 8);
	prop = of_get_property(np, "linux,bootx-linebytes", NULL);
	if (prop == NULL)
		prop = of_get_property(np, "linebytes", NULL);
	if (prop && *prop != 0xffffffffu)
		pitch = *prop;
	if (pitch == 1)
		pitch = 0x1000;
	prop = of_get_property(np, "linux,bootx-addr", NULL);
	if (prop == NULL)
		prop = of_get_property(np, "address", NULL);
	if (prop)
		address = *prop;

	/* FIXME: Add support for PCI reg properties. Right now, only
	 * reliable on macs
	 */
	if (address == 0)
		return -EINVAL;

	g_loc_X = 0;
	g_loc_Y = 0;
	g_max_loc_X = width / 8;
	g_max_loc_Y = height / 16;
	dispDeviceBase = (unsigned char *)address;
	dispDeviceRowBytes = pitch;
	dispDeviceDepth = depth == 15 ? 16 : depth;
	dispDeviceRect[0] = dispDeviceRect[1] = 0;
	dispDeviceRect[2] = width;
	dispDeviceRect[3] = height;

	btext_map();

	return 0;
}

int __init btext_find_display(int allow_nonstdout)
{
	struct device_node *np = of_stdout;
	int rc = -ENODEV;

	if (!of_node_is_type(np, "display")) {
		printk("boot stdout isn't a display !\n");
		np = NULL;
	}
	if (np)
		rc = btext_initialize(np);
	if (rc == 0 || !allow_nonstdout)
		return rc;

	for_each_node_by_type(np, "display") {
		if (of_property_read_bool(np, "linux,opened")) {
			printk("trying %pOF ...\n", np);
			rc = btext_initialize(np);
			printk("result: %d\n", rc);
		}
		if (rc == 0) {
			of_node_put(np);
			break;
		}
	}
	return rc;
}

/* Calc the base address of a given point (x,y) */
static unsigned char * calc_base(int x, int y)
{
	unsigned char *base;

	base = logicalDisplayBase;
	if (!base)
		base = dispDeviceBase;
	base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3);
	base += (y + dispDeviceRect[1]) * dispDeviceRowBytes;
	return base;
}

/* Adjust the display to a new resolution */
void btext_update_display(unsigned long phys, int width, int height,
			  int depth, int pitch)
{
	if (!dispDeviceBase)
		return;

	/* check it's the same frame buffer (within 256MB) */
	if ((phys ^ (unsigned long)dispDeviceBase) & 0xf0000000)
		return;

	dispDeviceBase = (__u8 *) phys;
	dispDeviceRect[0] = 0;
	dispDeviceRect[1] = 0;
	dispDeviceRect[2] = width;
	dispDeviceRect[3] = height;
	dispDeviceDepth = depth;
	dispDeviceRowBytes = pitch;
	if (boot_text_mapped) {
		iounmap(logicalDisplayBase);
		boot_text_mapped = 0;
	}
	btext_map();
	g_loc_X = 0;
	g_loc_Y = 0;
	g_max_loc_X = width / 8;
	g_max_loc_Y = height / 16;
}
EXPORT_SYMBOL(btext_update_display);

void __init btext_clearscreen(void)
{
	unsigned int *base	= (unsigned int *)calc_base(0, 0);
	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
					(dispDeviceDepth >> 3)) >> 2;
	int i,j;

	rmci_maybe_on();
	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
	{
		unsigned int *ptr = base;
		for(j=width; j; --j)
			*(ptr++) = 0;
		base += (dispDeviceRowBytes >> 2);
	}
	rmci_maybe_off();
}

void __init btext_flushscreen(void)
{
	unsigned int *base	= (unsigned int *)calc_base(0, 0);
	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
					(dispDeviceDepth >> 3)) >> 2;
	int i,j;

	for (i=0; i < (dispDeviceRect[3] - dispDeviceRect[1]); i++)
	{
		unsigned int *ptr = base;
		for(j = width; j > 0; j -= 8) {
			__asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
			ptr += 8;
		}
		base += (dispDeviceRowBytes >> 2);
	}
	__asm__ __volatile__ ("sync" ::: "memory");
}

void __init btext_flushline(void)
{
	unsigned int *base	= (unsigned int *)calc_base(0, g_loc_Y << 4);
	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
					(dispDeviceDepth >> 3)) >> 2;
	int i,j;

	for (i=0; i < 16; i++)
	{
		unsigned int *ptr = base;
		for(j = width; j > 0; j -= 8) {
			__asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
			ptr += 8;
		}
		base += (dispDeviceRowBytes >> 2);
	}
	__asm__ __volatile__ ("sync" ::: "memory");
}


#ifndef NO_SCROLL
static void scrollscreen(void)
{
	unsigned int *src     	= (unsigned int *)calc_base(0,16);
	unsigned int *dst     	= (unsigned int *)calc_base(0,0);
	unsigned long width    	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
				   (dispDeviceDepth >> 3)) >> 2;
	int i,j;

	rmci_maybe_on();

	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
	{
		unsigned int *src_ptr = src;
		unsigned int *dst_ptr = dst;
		for(j=width; j; --j)
			*(dst_ptr++) = *(src_ptr++);
		src += (dispDeviceRowBytes >> 2);
		dst += (dispDeviceRowBytes >> 2);
	}
	for (i=0; i<16; i++)
	{
		unsigned int *dst_ptr = dst;
		for(j=width; j; --j)
			*(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(const 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(const 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(const 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 int font_index = c * 16;
	const unsigned char *font = PTRRELOC(font_sun_8x16.data) + font_index;
	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;
#ifdef NO_SCROLL
	int x;
#endif
	if (!boot_text_mapped)
		return;

	switch (c) {
	case '\b':
		if (g_loc_X > 0)
			--g_loc_X;
		break;
	case '\t':
		g_loc_X = (g_loc_X & -8) + 8;
		break;
	case '\r':
		g_loc_X = 0;
		break;
	case '\n':
		g_loc_X = 0;
		g_loc_Y++;
		cline = 1;
		break;
	default:
		draw_byte(c, g_loc_X++, g_loc_Y);
	}
	if (g_loc_X >= g_max_loc_X) {
		g_loc_X = 0;
		g_loc_Y++;
		cline = 1;
	}
#ifndef NO_SCROLL
	while (g_loc_Y >= g_max_loc_Y) {
		scrollscreen();
		g_loc_Y--;
	}
#else
	/* wrap around from bottom to top of screen so we don't
	   waste time scrolling each line.  -- paulus. */
	if (g_loc_Y >= g_max_loc_Y)
		g_loc_Y = 0;
	if (cline) {
		for (x = 0; x < g_max_loc_X; ++x)
			draw_byte(' ', x, g_loc_Y);
	}
#endif
}

void btext_drawstring(const char *c)
{
	if (!boot_text_mapped)
		return;
	while (*c)
		btext_drawchar(*c++);
}

void __init btext_drawtext(const char *c, unsigned int len)
{
	if (!boot_text_mapped)
		return;
	while (len--)
		btext_drawchar(*c++);
}

void __init btext_drawhex(unsigned long v)
{
	if (!boot_text_mapped)
		return;
#ifdef CONFIG_PPC64
	btext_drawchar(hex_asc_hi(v >> 56));
	btext_drawchar(hex_asc_lo(v >> 56));
	btext_drawchar(hex_asc_hi(v >> 48));
	btext_drawchar(hex_asc_lo(v >> 48));
	btext_drawchar(hex_asc_hi(v >> 40));
	btext_drawchar(hex_asc_lo(v >> 40));
	btext_drawchar(hex_asc_hi(v >> 32));
	btext_drawchar(hex_asc_lo(v >> 32));
#endif
	btext_drawchar(hex_asc_hi(v >> 24));
	btext_drawchar(hex_asc_lo(v >> 24));
	btext_drawchar(hex_asc_hi(v >> 16));
	btext_drawchar(hex_asc_lo(v >> 16));
	btext_drawchar(hex_asc_hi(v >> 8));
	btext_drawchar(hex_asc_lo(v >> 8));
	btext_drawchar(hex_asc_hi(v));
	btext_drawchar(hex_asc_lo(v));
	btext_drawchar(' ');
}

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;
}
