// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * udbg for NS16550 compatible serial ports
 *
 * Copyright (C) 2001-2005 PPC 64 Team, IBM Corp
 */
#include <linux/types.h>
#include <asm/udbg.h>
#include <asm/io.h>
#include <asm/reg_a2.h>

extern u8 real_readb(volatile u8 __iomem  *addr);
extern void real_writeb(u8 data, volatile u8 __iomem *addr);
extern u8 real_205_readb(volatile u8 __iomem  *addr);
extern void real_205_writeb(u8 data, volatile u8 __iomem *addr);

#define UART_RBR	0
#define UART_IER	1
#define UART_FCR	2
#define UART_LCR	3
#define UART_MCR	4
#define UART_LSR	5
#define UART_MSR	6
#define UART_SCR	7
#define UART_THR	UART_RBR
#define UART_IIR	UART_FCR
#define UART_DLL	UART_RBR
#define UART_DLM	UART_IER
#define UART_DLAB	UART_LCR

#define LSR_DR   0x01  /* Data ready */
#define LSR_OE   0x02  /* Overrun */
#define LSR_PE   0x04  /* Parity error */
#define LSR_FE   0x08  /* Framing error */
#define LSR_BI   0x10  /* Break */
#define LSR_THRE 0x20  /* Xmit holding register empty */
#define LSR_TEMT 0x40  /* Xmitter empty */
#define LSR_ERR  0x80  /* Error */

#define LCR_DLAB 0x80

static u8 (*udbg_uart_in)(unsigned int reg);
static void (*udbg_uart_out)(unsigned int reg, u8 data);

static void udbg_uart_flush(void)
{
	if (!udbg_uart_in)
		return;

	/* wait for idle */
	while ((udbg_uart_in(UART_LSR) & LSR_THRE) == 0)
		cpu_relax();
}

static void udbg_uart_putc(char c)
{
	if (!udbg_uart_out)
		return;

	if (c == '\n')
		udbg_uart_putc('\r');
	udbg_uart_flush();
	udbg_uart_out(UART_THR, c);
}

static int udbg_uart_getc_poll(void)
{
	if (!udbg_uart_in)
		return -1;

	if (!(udbg_uart_in(UART_LSR) & LSR_DR))
		return udbg_uart_in(UART_RBR);

	return -1;
}

static int udbg_uart_getc(void)
{
	if (!udbg_uart_in)
		return -1;
	/* wait for char */
	while (!(udbg_uart_in(UART_LSR) & LSR_DR))
		cpu_relax();
	return udbg_uart_in(UART_RBR);
}

static void __init udbg_use_uart(void)
{
	udbg_putc = udbg_uart_putc;
	udbg_flush = udbg_uart_flush;
	udbg_getc = udbg_uart_getc;
	udbg_getc_poll = udbg_uart_getc_poll;
}

void __init udbg_uart_setup(unsigned int speed, unsigned int clock)
{
	unsigned int dll, base_bauds;

	if (!udbg_uart_out)
		return;

	if (clock == 0)
		clock = 1843200;
	if (speed == 0)
		speed = 9600;

	base_bauds = clock / 16;
	dll = base_bauds / speed;

	udbg_uart_out(UART_LCR, 0x00);
	udbg_uart_out(UART_IER, 0xff);
	udbg_uart_out(UART_IER, 0x00);
	udbg_uart_out(UART_LCR, LCR_DLAB);
	udbg_uart_out(UART_DLL, dll & 0xff);
	udbg_uart_out(UART_DLM, dll >> 8);
	/* 8 data, 1 stop, no parity */
	udbg_uart_out(UART_LCR, 0x3);
	/* RTS/DTR */
	udbg_uart_out(UART_MCR, 0x3);
	/* Clear & enable FIFOs */
	udbg_uart_out(UART_FCR, 0x7);
}

unsigned int __init udbg_probe_uart_speed(unsigned int clock)
{
	unsigned int dll, dlm, divisor, prescaler, speed;
	u8 old_lcr;

	old_lcr = udbg_uart_in(UART_LCR);

	/* select divisor latch registers.  */
	udbg_uart_out(UART_LCR, old_lcr | LCR_DLAB);

	/* now, read the divisor */
	dll = udbg_uart_in(UART_DLL);
	dlm = udbg_uart_in(UART_DLM);
	divisor = dlm << 8 | dll;

	/* check prescaling */
	if (udbg_uart_in(UART_MCR) & 0x80)
		prescaler = 4;
	else
		prescaler = 1;

	/* restore the LCR */
	udbg_uart_out(UART_LCR, old_lcr);

	/* calculate speed */
	speed = (clock / prescaler) / (divisor * 16);

	/* sanity check */
	if (speed > (clock / 16))
		speed = 9600;

	return speed;
}

static union {
	unsigned char __iomem *mmio_base;
	unsigned long pio_base;
} udbg_uart;

static unsigned int udbg_uart_stride = 1;

static u8 udbg_uart_in_pio(unsigned int reg)
{
	return inb(udbg_uart.pio_base + (reg * udbg_uart_stride));
}

static void udbg_uart_out_pio(unsigned int reg, u8 data)
{
	outb(data, udbg_uart.pio_base + (reg * udbg_uart_stride));
}

void __init udbg_uart_init_pio(unsigned long port, unsigned int stride)
{
	if (!port)
		return;
	udbg_uart.pio_base = port;
	udbg_uart_stride = stride;
	udbg_uart_in = udbg_uart_in_pio;
	udbg_uart_out = udbg_uart_out_pio;
	udbg_use_uart();
}

static u8 udbg_uart_in_mmio(unsigned int reg)
{
	return in_8(udbg_uart.mmio_base + (reg * udbg_uart_stride));
}

static void udbg_uart_out_mmio(unsigned int reg, u8 data)
{
	out_8(udbg_uart.mmio_base + (reg * udbg_uart_stride), data);
}


void __init udbg_uart_init_mmio(void __iomem *addr, unsigned int stride)
{
	if (!addr)
		return;
	udbg_uart.mmio_base = addr;
	udbg_uart_stride = stride;
	udbg_uart_in = udbg_uart_in_mmio;
	udbg_uart_out = udbg_uart_out_mmio;
	udbg_use_uart();
}

#ifdef CONFIG_PPC_MAPLE

#define UDBG_UART_MAPLE_ADDR	((void __iomem *)0xf40003f8)

static u8 udbg_uart_in_maple(unsigned int reg)
{
	return real_readb(UDBG_UART_MAPLE_ADDR + reg);
}

static void udbg_uart_out_maple(unsigned int reg, u8 val)
{
	real_writeb(val, UDBG_UART_MAPLE_ADDR + reg);
}

void __init udbg_init_maple_realmode(void)
{
	udbg_uart_in = udbg_uart_in_maple;
	udbg_uart_out = udbg_uart_out_maple;
	udbg_use_uart();
}

#endif /* CONFIG_PPC_MAPLE */

#ifdef CONFIG_PPC_PASEMI

#define UDBG_UART_PAS_ADDR	((void __iomem *)0xfcff03f8UL)

static u8 udbg_uart_in_pas(unsigned int reg)
{
	return real_205_readb(UDBG_UART_PAS_ADDR + reg);
}

static void udbg_uart_out_pas(unsigned int reg, u8 val)
{
	real_205_writeb(val, UDBG_UART_PAS_ADDR + reg);
}

void __init udbg_init_pas_realmode(void)
{
	udbg_uart_in = udbg_uart_in_pas;
	udbg_uart_out = udbg_uart_out_pas;
	udbg_use_uart();
}

#endif /* CONFIG_PPC_PASEMI */

#ifdef CONFIG_PPC_EARLY_DEBUG_44x

#include <platforms/44x/44x.h>

static u8 udbg_uart_in_44x_as1(unsigned int reg)
{
	return as1_readb((void __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR + reg);
}

static void udbg_uart_out_44x_as1(unsigned int reg, u8 val)
{
	as1_writeb(val, (void __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR + reg);
}

void __init udbg_init_44x_as1(void)
{
	udbg_uart_in = udbg_uart_in_44x_as1;
	udbg_uart_out = udbg_uart_out_44x_as1;
	udbg_use_uart();
}

#endif /* CONFIG_PPC_EARLY_DEBUG_44x */

#ifdef CONFIG_PPC_EARLY_DEBUG_40x

static u8 udbg_uart_in_40x(unsigned int reg)
{
	return real_readb((void __iomem *)CONFIG_PPC_EARLY_DEBUG_40x_PHYSADDR
			  + reg);
}

static void udbg_uart_out_40x(unsigned int reg, u8 val)
{
	real_writeb(val, (void __iomem *)CONFIG_PPC_EARLY_DEBUG_40x_PHYSADDR
		    + reg);
}

void __init udbg_init_40x_realmode(void)
{
	udbg_uart_in = udbg_uart_in_40x;
	udbg_uart_out = udbg_uart_out_40x;
	udbg_use_uart();
}

#endif /* CONFIG_PPC_EARLY_DEBUG_40x */

#ifdef CONFIG_PPC_EARLY_DEBUG_MICROWATT

#define UDBG_UART_MW_ADDR	((void __iomem *)0xc0002000)

static u8 udbg_uart_in_isa300_rm(unsigned int reg)
{
	uint64_t msr = mfmsr();
	uint8_t  c;

	mtmsr(msr & ~(MSR_EE|MSR_DR));
	isync();
	eieio();
	c = __raw_rm_readb(UDBG_UART_MW_ADDR + (reg << 2));
	mtmsr(msr);
	isync();
	return c;
}

static void udbg_uart_out_isa300_rm(unsigned int reg, u8 val)
{
	uint64_t msr = mfmsr();

	mtmsr(msr & ~(MSR_EE|MSR_DR));
	isync();
	eieio();
	__raw_rm_writeb(val, UDBG_UART_MW_ADDR + (reg << 2));
	mtmsr(msr);
	isync();
}

void __init udbg_init_debug_microwatt(void)
{
	udbg_uart_in = udbg_uart_in_isa300_rm;
	udbg_uart_out = udbg_uart_out_isa300_rm;
	udbg_use_uart();
}

#endif /* CONFIG_PPC_EARLY_DEBUG_MICROWATT */
