// 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 <linux/of_address.h>

#include <mm/mmu_decl.h>

#include <asm/io.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 *__init 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 *__init 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 */

