/*
 * (C) Copyright 2002
 * Stäubli Faverges - <www.staubli.com>
 * Pierre AUBERT  p.aubert@staubli.com
 *
 * (C) Copyright 2005
 * Martin Krause TQ-Systems GmbH martin.krause@tqs.de
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/*
 * Basic video support for SMI SM501 "Voyager" graphic controller
 */

#include <common.h>

#include <asm/io.h>
#include <pci.h>
#include <video_fb.h>
#include <sm501.h>

#define read8(ptrReg)                \
    *(volatile unsigned char *)(sm501.isaBase + ptrReg)

#define write8(ptrReg,value) \
    *(volatile unsigned char *)(sm501.isaBase + ptrReg) = value

#define read16(ptrReg) \
    (*(volatile unsigned short *)(sm501.isaBase + ptrReg))

#define write16(ptrReg,value) \
    (*(volatile unsigned short *)(sm501.isaBase + ptrReg) = value)

#define read32(ptrReg) \
    (*(volatile unsigned int *)(sm501.isaBase + ptrReg))

#define write32(ptrReg, value) \
    (*(volatile unsigned int *)(sm501.isaBase + ptrReg) = value)

GraphicDevice sm501;

void write_be32(int off, unsigned int val)
{
	out_be32((unsigned __iomem *)(sm501.isaBase + off), val);
}

void write_le32(int off, unsigned int val)
{
	out_le32((unsigned __iomem *)(sm501.isaBase + off), val);
}

void (*write_reg32)(int off, unsigned int val) = write_be32;

/*-----------------------------------------------------------------------------
 * SmiSetRegs --
 *-----------------------------------------------------------------------------
 */
static void SmiSetRegs (void)
{
	/*
	 * The content of the chipset register depends on the board (clocks,
	 * ...)
	 */
	const SMI_REGS *preg = board_get_regs ();
	while (preg->Index) {
		write_reg32 (preg->Index, preg->Value);
		/*
		 * Insert a delay between
		 */
		udelay (1000);
		preg ++;
	}
}

#ifdef CONFIG_VIDEO_SM501_PCI
static struct pci_device_id sm501_pci_tbl[] = {
	{ PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_501 },
	{}
};
#endif

/*
 * We do not enforce board code to provide empty/unused
 * functions for this driver and define weak default
 * functions here.
 */
unsigned int __board_video_init (void)
{
	return 0;
}

unsigned int board_video_init (void)
			__attribute__((weak, alias("__board_video_init")));

unsigned int __board_video_get_fb (void)
{
	return 0;
}

unsigned int board_video_get_fb (void)
			__attribute__((weak, alias("__board_video_get_fb")));

void __board_validate_screen (unsigned int base)
{
}

void board_validate_screen (unsigned int base)
			__attribute__((weak, alias("__board_validate_screen")));

/*-----------------------------------------------------------------------------
 * video_hw_init --
 *-----------------------------------------------------------------------------
 */
void *video_hw_init (void)
{
#ifdef CONFIG_VIDEO_SM501_PCI
	unsigned int pci_mem_base, pci_mmio_base;
	unsigned int id;
	unsigned short device_id;
	pci_dev_t devbusfn;
	int mem;
#endif
	unsigned int *vm, i;

	memset (&sm501, 0, sizeof (GraphicDevice));

#ifdef CONFIG_VIDEO_SM501_PCI
	printf("Video: ");

	/* Look for SM501/SM502 chips */
	devbusfn = pci_find_devices(sm501_pci_tbl, 0);
	if (devbusfn < 0) {
		printf ("PCI Controller not found.\n");
		goto not_pci;
	}

	/* Setup */
	pci_write_config_dword (devbusfn, PCI_COMMAND,
				(PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
	pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
	pci_read_config_dword (devbusfn, PCI_REVISION_ID, &id);
	pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
	pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_1, &pci_mmio_base);
	sm501.frameAdrs = pci_mem_to_phys (devbusfn, pci_mem_base);
	sm501.isaBase = pci_mem_to_phys (devbusfn, pci_mmio_base);

	if (sm501.isaBase)
		write_reg32 = write_le32;

	mem = in_le32 ((unsigned __iomem *)(sm501.isaBase + 0x10));
	mem = (mem & 0x0000e000) >> 13;
	switch (mem) {
	case 1:
		mem = 8;
		break;
	case 2:
		mem = 16;
		break;
	case 3:
		mem = 32;
		break;
	case 4:
		mem = 64;
		break;
	case 5:
		mem = 2;
		break;
	case 0:
	default:
		mem = 4;
	}
	printf ("PCI SM50%d %d MB\n", ((id & 0xff) == 0xC0) ? 2 : 1, mem);
not_pci:
#endif
	/*
	 * Initialization of the access to the graphic chipset Retreive base
	 * address of the chipset (see board/RPXClassic/eccx.c)
	 */
	if (!sm501.isaBase) {
		sm501.isaBase = board_video_init ();
		if (!sm501.isaBase)
			return NULL;
	}

	if (!sm501.frameAdrs) {
		sm501.frameAdrs = board_video_get_fb ();
		if (!sm501.frameAdrs)
			return NULL;
	}

	sm501.winSizeX = board_get_width ();
	sm501.winSizeY = board_get_height ();

#if defined(CONFIG_VIDEO_SM501_8BPP)
	sm501.gdfIndex = GDF__8BIT_INDEX;
	sm501.gdfBytesPP = 1;

#elif defined(CONFIG_VIDEO_SM501_16BPP)
	sm501.gdfIndex = GDF_16BIT_565RGB;
	sm501.gdfBytesPP = 2;

#elif defined(CONFIG_VIDEO_SM501_32BPP)
	sm501.gdfIndex = GDF_32BIT_X888RGB;
	sm501.gdfBytesPP = 4;
#else
#error Unsupported SM501 BPP
#endif

	sm501.memSize = sm501.winSizeX * sm501.winSizeY * sm501.gdfBytesPP;

	/* Load Smi registers */
	SmiSetRegs ();

	/* (see board/RPXClassic/RPXClassic.c) */
	board_validate_screen (sm501.isaBase);

	/* Clear video memory */
	i = sm501.memSize/4;
	vm = (unsigned int *)sm501.frameAdrs;
	while(i--)
		*vm++ = 0;

	return (&sm501);
}
