// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c
 *
 * udbg serial input/output routines for the USB Gecko adapter.
 * Copyright (C) 2008-2009 The GameCube Linux Team
 * Copyright (C) 2008,2009 Albert Herranz
 */

#include <mm/mmu_decl.h>

#include <asm/io.h>
#include <asm/prom.h>
#include <asm/udbg.h>
#include <asm/fixmap.h>

#include "usbgecko_udbg.h"


#define EXI_CLK_32MHZ           5

#define EXI_CSR                 0x00
#define   EXI_CSR_CLKMASK       (0x7<<4)
#define     EXI_CSR_CLK_32MHZ   (EXI_CLK_32MHZ<<4)
#define   EXI_CSR_CSMASK        (0x7<<7)
#define     EXI_CSR_CS_0        (0x1<<7)  /* Chip Select 001 */

#define EXI_CR                  0x0c
#define   EXI_CR_TSTART         (1<<0)
#define   EXI_CR_WRITE		(1<<2)
#define   EXI_CR_READ_WRITE     (2<<2)
#define   EXI_CR_TLEN(len)      (((len)-1)<<4)

#define EXI_DATA                0x10

#define UG_READ_ATTEMPTS	100
#define UG_WRITE_ATTEMPTS	100


static void __iomem *ug_io_base;

/*
 * Performs one input/output transaction between the exi host and the usbgecko.
 */
static u32 ug_io_transaction(u32 in)
{
	u32 __iomem *csr_reg = ug_io_base + EXI_CSR;
	u32 __iomem *data_reg = ug_io_base + EXI_DATA;
	u32 __iomem *cr_reg = ug_io_base + EXI_CR;
	u32 csr, data, cr;

	/* select */
	csr = EXI_CSR_CLK_32MHZ | EXI_CSR_CS_0;
	out_be32(csr_reg, csr);

	/* read/write */
	data = in;
	out_be32(data_reg, data);
	cr = EXI_CR_TLEN(2) | EXI_CR_READ_WRITE | EXI_CR_TSTART;
	out_be32(cr_reg, cr);

	while (in_be32(cr_reg) & EXI_CR_TSTART)
		barrier();

	/* deselect */
	out_be32(csr_reg, 0);

	/* result */
	data = in_be32(data_reg);

	return data;
}

/*
 * Returns true if an usbgecko adapter is found.
 */
static int ug_is_adapter_present(void)
{
	if (!ug_io_base)
		return 0;

	return ug_io_transaction(0x90000000) == 0x04700000;
}

/*
 * Returns true if the TX fifo is ready for transmission.
 */
static int ug_is_txfifo_ready(void)
{
	return ug_io_transaction(0xc0000000) & 0x04000000;
}

/*
 * Tries to transmit a character.
 * If the TX fifo is not ready the result is undefined.
 */
static void ug_raw_putc(char ch)
{
	ug_io_transaction(0xb0000000 | (ch << 20));
}

/*
 * Transmits a character.
 * It silently fails if the TX fifo is not ready after a number of retries.
 */
static void ug_putc(char ch)
{
	int count = UG_WRITE_ATTEMPTS;

	if (!ug_io_base)
		return;

	if (ch == '\n')
		ug_putc('\r');

	while (!ug_is_txfifo_ready() && count--)
		barrier();
	if (count >= 0)
		ug_raw_putc(ch);
}

/*
 * Returns true if the RX fifo is ready for transmission.
 */
static int ug_is_rxfifo_ready(void)
{
	return ug_io_transaction(0xd0000000) & 0x04000000;
}

/*
 * Tries to receive a character.
 * If a character is unavailable the function returns -1.
 */
static int ug_raw_getc(void)
{
	u32 data = ug_io_transaction(0xa0000000);
	if (data & 0x08000000)
		return (data >> 16) & 0xff;
	else
		return -1;
}

/*
 * Receives a character.
 * It fails if the RX fifo is not ready after a number of retries.
 */
static int ug_getc(void)
{
	int count = UG_READ_ATTEMPTS;

	if (!ug_io_base)
		return -1;

	while (!ug_is_rxfifo_ready() && count--)
		barrier();
	return ug_raw_getc();
}

/*
 * udbg functions.
 *
 */

/*
 * Transmits a character.
 */
static void ug_udbg_putc(char ch)
{
	ug_putc(ch);
}

/*
 * Receives a character. Waits until a character is available.
 */
static int ug_udbg_getc(void)
{
	int ch;

	while ((ch = ug_getc()) == -1)
		barrier();
	return ch;
}

/*
 * Receives a character. If a character is not available, returns -1.
 */
static int ug_udbg_getc_poll(void)
{
	if (!ug_is_rxfifo_ready())
		return -1;
	return ug_getc();
}

/*
 * Retrieves and prepares the virtual address needed to access the hardware.
 */
static void __iomem *ug_udbg_setup_exi_io_base(struct device_node *np)
{
	void __iomem *exi_io_base = NULL;
	phys_addr_t paddr;
	const unsigned int *reg;

	reg = of_get_property(np, "reg", NULL);
	if (reg) {
		paddr = of_translate_address(np, reg);
		if (paddr)
			exi_io_base = ioremap(paddr, reg[1]);
	}
	return exi_io_base;
}

/*
 * Checks if a USB Gecko adapter is inserted in any memory card slot.
 */
static void __iomem *ug_udbg_probe(void __iomem *exi_io_base)
{
	int i;

	/* look for a usbgecko on memcard slots A and B */
	for (i = 0; i < 2; i++) {
		ug_io_base = exi_io_base + 0x14 * i;
		if (ug_is_adapter_present())
			break;
	}
	if (i == 2)
		ug_io_base = NULL;
	return ug_io_base;

}

/*
 * USB Gecko udbg support initialization.
 */
void __init ug_udbg_init(void)
{
	struct device_node *np;
	void __iomem *exi_io_base;

	if (ug_io_base)
		udbg_printf("%s: early -> final\n", __func__);

	np = of_find_compatible_node(NULL, NULL, "nintendo,flipper-exi");
	if (!np) {
		udbg_printf("%s: EXI node not found\n", __func__);
		goto out;
	}

	exi_io_base = ug_udbg_setup_exi_io_base(np);
	if (!exi_io_base) {
		udbg_printf("%s: failed to setup EXI io base\n", __func__);
		goto done;
	}

	if (!ug_udbg_probe(exi_io_base)) {
		udbg_printf("usbgecko_udbg: not found\n");
		iounmap(exi_io_base);
	} else {
		udbg_putc = ug_udbg_putc;
		udbg_getc = ug_udbg_getc;
		udbg_getc_poll = ug_udbg_getc_poll;
		udbg_printf("usbgecko_udbg: ready\n");
	}

done:
	of_node_put(np);
out:
	return;
}

#ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO

static phys_addr_t __init ug_early_grab_io_addr(void)
{
#if defined(CONFIG_GAMECUBE)
	return 0x0c000000;
#elif defined(CONFIG_WII)
	return 0x0d000000;
#else
#error Invalid platform for USB Gecko based early debugging.
#endif
}

/*
 * USB Gecko early debug support initialization for udbg.
 */
void __init udbg_init_usbgecko(void)
{
	void __iomem *early_debug_area;
	void __iomem *exi_io_base;

	/*
	 * At this point we have a BAT already setup that enables I/O
	 * to the EXI hardware.
	 *
	 * The BAT uses a virtual address range reserved at the fixmap.
	 * This must match the virtual address configured in
	 * head_32.S:setup_usbgecko_bat().
	 */
	early_debug_area = (void __iomem *)__fix_to_virt(FIX_EARLY_DEBUG_BASE);
	exi_io_base = early_debug_area + 0x00006800;

	/* try to detect a USB Gecko */
	if (!ug_udbg_probe(exi_io_base))
		return;

	/* we found a USB Gecko, load udbg hooks */
	udbg_putc = ug_udbg_putc;
	udbg_getc = ug_udbg_getc;
	udbg_getc_poll = ug_udbg_getc_poll;

	/*
	 * Prepare again the same BAT for MMU_init.
	 * This allows udbg I/O to continue working after the MMU is
	 * turned on for real.
	 * It is safe to continue using the same virtual address as it is
	 * a reserved fixmap area.
	 */
	setbat(1, (unsigned long)early_debug_area,
	       ug_early_grab_io_addr(), 128*1024, PAGE_KERNEL_NCG);
}

#endif /* CONFIG_PPC_EARLY_DEBUG_USBGECKO */

