/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/mach-rpc/include/mach/uncompress.h
 *
 *  Copyright (C) 1996 Russell King
 */
#define VIDMEM ((char *)SCREEN_START)
 
#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/setup.h>
#include <asm/page.h>

int video_size_row;
unsigned char bytes_per_char_h;
extern unsigned long con_charconvtable[256];

struct param_struct {
	unsigned long page_size;
	unsigned long nr_pages;
	unsigned long ramdisk_size;
	unsigned long mountrootrdonly;
	unsigned long rootdev;
	unsigned long video_num_cols;
	unsigned long video_num_rows;
	unsigned long video_x;
	unsigned long video_y;
	unsigned long memc_control_reg;
	unsigned char sounddefault;
	unsigned char adfsdrives;
	unsigned char bytes_per_char_h;
	unsigned char bytes_per_char_v;
	unsigned long unused[256/4-11];
};

static const unsigned long palette_4[16] = {
	0x00000000,
	0x000000cc,
	0x0000cc00,             /* Green   */
	0x0000cccc,             /* Yellow  */
	0x00cc0000,             /* Blue    */
	0x00cc00cc,             /* Magenta */
	0x00cccc00,             /* Cyan    */
	0x00cccccc,             /* White   */
	0x00000000,
	0x000000ff,
	0x0000ff00,
	0x0000ffff,
	0x00ff0000,
	0x00ff00ff,
	0x00ffff00,
	0x00ffffff
};

#define palette_setpixel(p)	*(unsigned long *)(IO_START+0x00400000) = 0x10000000|((p) & 255)
#define palette_write(v)	*(unsigned long *)(IO_START+0x00400000) = 0x00000000|((v) & 0x00ffffff)

/*
 * params_phys is a linker defined symbol - see
 * arch/arm/boot/compressed/Makefile
 */
extern __attribute__((pure)) struct param_struct *params(void);
#define params (params())

#ifndef STANDALONE_DEBUG 
unsigned long video_num_cols;
unsigned long video_num_rows;
unsigned long video_x;
unsigned long video_y;
unsigned char bytes_per_char_v;
int white;

/*
 * This does not append a newline
 */
static inline void putc(int c)
{
	extern void ll_write_char(char *, char c, char white);
	int x,y;
	char *ptr;

	x = video_x;
	y = video_y;

	if (c == '\n') {
		if (++y >= video_num_rows)
			y--;
	} else if (c == '\r') {
		x = 0;
	} else {
		ptr = VIDMEM + ((y*video_num_cols*bytes_per_char_v+x)*bytes_per_char_h);
		ll_write_char(ptr, c, white);
		if (++x >= video_num_cols) {
			x = 0;
			if ( ++y >= video_num_rows ) {
				y--;
			}
		}
	}

	video_x = x;
	video_y = y;
}

static inline void flush(void)
{
}

/*
 * Setup for decompression
 */
static void arch_decomp_setup(void)
{
	int i;
	struct tag *t = (struct tag *)params;
	unsigned int nr_pages = 0, page_size = PAGE_SIZE;

	if (t->hdr.tag == ATAG_CORE) {
		for (; t->hdr.size; t = tag_next(t)) {
			if (t->hdr.tag == ATAG_VIDEOTEXT) {
				video_num_rows = t->u.videotext.video_lines;
				video_num_cols = t->u.videotext.video_cols;
				video_x = t->u.videotext.x;
				video_y = t->u.videotext.y;
			} else if (t->hdr.tag == ATAG_VIDEOLFB) {
				bytes_per_char_h = t->u.videolfb.lfb_depth;
				bytes_per_char_v = 8;
			} else if (t->hdr.tag == ATAG_MEM) {
				page_size = PAGE_SIZE;
				nr_pages += (t->u.mem.size / PAGE_SIZE);
			}
		}
	} else {
		nr_pages = params->nr_pages;
		page_size = params->page_size;
		video_num_rows = params->video_num_rows;
		video_num_cols = params->video_num_cols;
		video_x = params->video_x;
		video_y = params->video_y;
		bytes_per_char_h = params->bytes_per_char_h;
		bytes_per_char_v = params->bytes_per_char_v;
	}

	video_size_row = video_num_cols * bytes_per_char_h;
	
	if (bytes_per_char_h == 4)
		for (i = 0; i < 256; i++)
			con_charconvtable[i] =
				(i & 128 ? 1 << 0  : 0) |
				(i & 64  ? 1 << 4  : 0) |
				(i & 32  ? 1 << 8  : 0) |
				(i & 16  ? 1 << 12 : 0) |
				(i & 8   ? 1 << 16 : 0) |
				(i & 4   ? 1 << 20 : 0) |
				(i & 2   ? 1 << 24 : 0) |
				(i & 1   ? 1 << 28 : 0);
	else
		for (i = 0; i < 16; i++)
			con_charconvtable[i] =
				(i & 8   ? 1 << 0  : 0) |
				(i & 4   ? 1 << 8  : 0) |
				(i & 2   ? 1 << 16 : 0) |
				(i & 1   ? 1 << 24 : 0);


	palette_setpixel(0);
	if (bytes_per_char_h == 1) {
		palette_write (0);
		palette_write (0x00ffffff);
		for (i = 2; i < 256; i++)
			palette_write (0);
		white = 1;
	} else {
		for (i = 0; i < 256; i++)
			palette_write (i < 16 ? palette_4[i] : 0);
		white = 7;
	}

	if (nr_pages * page_size < 4096*1024) error("<4M of mem\n");
}
#endif
