// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * udbg for zilog scc ports as found on Apple PowerMacs
 *
 * Copyright (C) 2001-2005 PPC 64 Team, IBM Corp
 */
#include <linux/types.h>
#include <linux/of.h>
#include <asm/udbg.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/pmac_feature.h>

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

#define	SCC_TXRDY	4
#define SCC_RXRDY	1

static volatile u8 __iomem *sccc;
static volatile u8 __iomem *sccd;

static void udbg_scc_putc(char c)
{
	if (sccc) {
		while ((in_8(sccc) & SCC_TXRDY) == 0)
			;
		out_8(sccd,  c);
		if (c == '\n')
			udbg_scc_putc('\r');
	}
}

static int udbg_scc_getc_poll(void)
{
	if (sccc) {
		if ((in_8(sccc) & SCC_RXRDY) != 0)
			return in_8(sccd);
		else
			return -1;
	}
	return -1;
}

static int udbg_scc_getc(void)
{
	if (sccc) {
		while ((in_8(sccc) & SCC_RXRDY) == 0)
			;
		return in_8(sccd);
	}
	return -1;
}

static unsigned char scc_inittab[] = {
    13, 0,		/* set baud rate divisor */
    12, 0,
    14, 1,		/* baud rate gen enable, src=rtxc */
    11, 0x50,		/* clocks = br gen */
    5,  0xea,		/* tx 8 bits, assert DTR & RTS */
    4,  0x46,		/* x16 clock, 1 stop */
    3,  0xc1,		/* rx enable, 8 bits */
};

void __init udbg_scc_init(int force_scc)
{
	const u32 *reg;
	unsigned long addr;
	struct device_node *stdout = NULL, *escc = NULL, *macio = NULL;
	struct device_node *ch, *ch_def = NULL, *ch_a = NULL;
	const char *path;
	int i;

	escc = of_find_node_by_name(NULL, "escc");
	if (escc == NULL)
		goto bail;
	macio = of_get_parent(escc);
	if (macio == NULL)
		goto bail;
	path = of_get_property(of_chosen, "linux,stdout-path", NULL);
	if (path != NULL)
		stdout = of_find_node_by_path(path);
	for_each_child_of_node(escc, ch) {
		if (ch == stdout) {
			of_node_put(ch_def);
			ch_def = of_node_get(ch);
		}
		if (of_node_name_eq(ch, "ch-a")) {
			of_node_put(ch_a);
			ch_a = of_node_get(ch);
		}
	}
	if (ch_def == NULL && !force_scc)
		goto bail;

	ch = ch_def ? ch_def : ch_a;

	/* Get address within mac-io ASIC */
	reg = of_get_property(escc, "reg", NULL);
	if (reg == NULL)
		goto bail;
	addr = reg[0];

	/* Get address of mac-io PCI itself */
	reg = of_get_property(macio, "assigned-addresses", NULL);
	if (reg == NULL)
		goto bail;
	addr += reg[2];

	/* Lock the serial port */
	pmac_call_feature(PMAC_FTR_SCC_ENABLE, ch,
			  PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);

	if (ch == ch_a)
		addr += 0x20;
	sccc = ioremap(addr & PAGE_MASK, PAGE_SIZE) ;
	sccc += addr & ~PAGE_MASK;
	sccd = sccc + 0x10;

	mb();

	for (i = 20000; i != 0; --i)
		in_8(sccc);
	out_8(sccc, 0x09);		/* reset A or B side */
	out_8(sccc, 0xc0);

	/* If SCC was the OF output port, read the BRG value, else
	 * Setup for 38400 or 57600 8N1 depending on the machine
	 */
	if (ch_def != NULL) {
		out_8(sccc, 13);
		scc_inittab[1] = in_8(sccc);
		out_8(sccc, 12);
		scc_inittab[3] = in_8(sccc);
	} else if (of_machine_is_compatible("RackMac1,1")
		   || of_machine_is_compatible("RackMac1,2")
		   || of_machine_is_compatible("MacRISC4")) {
		/* Xserves and G5s default to 57600 */
		scc_inittab[1] = 0;
		scc_inittab[3] = 0;
	} else {
		/* Others default to 38400 */
		scc_inittab[1] = 0;
		scc_inittab[3] = 1;
	}

	for (i = 0; i < sizeof(scc_inittab); ++i)
		out_8(sccc, scc_inittab[i]);


	udbg_putc = udbg_scc_putc;
	udbg_getc = udbg_scc_getc;
	udbg_getc_poll = udbg_scc_getc_poll;

	udbg_puts("Hello World !\n");

 bail:
	of_node_put(macio);
	of_node_put(escc);
	of_node_put(stdout);
	of_node_put(ch_def);
	of_node_put(ch_a);
}

#ifdef CONFIG_PPC64
static void udbg_real_scc_putc(char c)
{
	while ((real_readb(sccc) & SCC_TXRDY) == 0)
		;
	real_writeb(c, sccd);
	if (c == '\n')
		udbg_real_scc_putc('\r');
}

void __init udbg_init_pmac_realmode(void)
{
	sccc = (volatile u8 __iomem *)0x80013020ul;
	sccd = (volatile u8 __iomem *)0x80013030ul;

	udbg_putc = udbg_real_scc_putc;
	udbg_getc = NULL;
	udbg_getc_poll = NULL;
}
#endif /* CONFIG_PPC64 */
