// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2000
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 */

#include <common.h>
#include <command.h>
#include <dm.h>
#include <serial.h>
#include <watchdog.h>
#include <asm/cpm_8xx.h>
#include <asm/global_data.h>
#include <linux/compiler.h>

DECLARE_GLOBAL_DATA_PTR;

#if defined(CONFIG_8xx_CONS_SMC1)	/* Console on SMC1 */
#define	SMC_INDEX	0
#define PROFF_SMC	PROFF_SMC1
#define CPM_CR_CH_SMC	CPM_CR_CH_SMC1
#define IOPINS		0xc0

#elif defined(CONFIG_8xx_CONS_SMC2)	/* Console on SMC2 */
#define SMC_INDEX	1
#define PROFF_SMC	PROFF_SMC2
#define CPM_CR_CH_SMC	CPM_CR_CH_SMC2
#define IOPINS		0xc00

#endif /* CONFIG_8xx_CONS_SMCx */

struct serialbuffer {
	cbd_t	rxbd;		/* Rx BD */
	cbd_t	txbd;		/* Tx BD */
	uint	rxindex;	/* index for next character to read */
	uchar	rxbuf[CONFIG_SYS_SMC_RXBUFLEN];/* rx buffers */
	uchar	txbuf;	/* tx buffers */
};

static void serial_setdivisor(cpm8xx_t __iomem *cp, int baudrate)
{
	int divisor = (gd->cpu_clk + 8 * baudrate) / 16 / baudrate;

	if (divisor / 16 > 0x1000) {
		/* bad divisor, assume 50MHz clock and 9600 baud */
		divisor = (50 * 1000 * 1000 + 8 * 9600) / 16 / 9600;
	}

	divisor /= CONFIG_SYS_BRGCLK_PRESCALE;

	if (divisor <= 0x1000)
		out_be32(&cp->cp_brgc1, ((divisor - 1) << 1) | CPM_BRG_EN);
	else
		out_be32(&cp->cp_brgc1, ((divisor / 16 - 1) << 1) | CPM_BRG_EN |
			 CPM_BRG_DIV16);
}

/*
 * Minimal serial functions needed to use one of the SMC ports
 * as serial console interface.
 */

static int serial_mpc8xx_setbrg(struct udevice *dev, int baudrate)
{
	immap_t __iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR;
	cpm8xx_t __iomem *cp = &(im->im_cpm);

	/* Set up the baud rate generator.
	 * See 8xx_io/commproc.c for details.
	 *
	 * Wire BRG1 to SMCx
	 */

	out_be32(&cp->cp_simode, 0);

	serial_setdivisor(cp, baudrate);

	return 0;
}

static int serial_mpc8xx_probe(struct udevice *dev)
{
	immap_t __iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR;
	smc_t __iomem *sp;
	smc_uart_t __iomem *up;
	u16 smc_rpbase;
	cpm8xx_t __iomem *cp = &(im->im_cpm);
	struct serialbuffer __iomem *rtx;

	/* initialize pointers to SMC */

	sp = cp->cp_smc + SMC_INDEX;
	up = (smc_uart_t __iomem *)&cp->cp_dpmem[PROFF_SMC];

	smc_rpbase = in_be16(&up->smc_rpbase);
	if (smc_rpbase)
		up = (smc_uart_t __iomem *)&cp->cp_dpmem[smc_rpbase];

	/* Disable transmitter/receiver. */
	clrbits_be16(&sp->smc_smcmr, SMCMR_REN | SMCMR_TEN);

	/* Enable SDMA. */
	out_be32(&im->im_siu_conf.sc_sdcr, 1);

	/* clear error conditions */
	out_8(&im->im_sdma.sdma_sdsr, CONFIG_SYS_SDSR);

	/* clear SDMA interrupt mask */
	out_8(&im->im_sdma.sdma_sdmr, CONFIG_SYS_SDMR);

	/* Use Port B for SMCx instead of other functions. */
	setbits_be32(&cp->cp_pbpar, IOPINS);
	clrbits_be32(&cp->cp_pbdir, IOPINS);
	clrbits_be16(&cp->cp_pbodr, IOPINS);

	/* Set the physical address of the host memory buffers in
	 * the buffer descriptors.
	 */
	rtx = (struct serialbuffer __iomem *)&cp->cp_dpmem[CPM_SERIAL_BASE];
	/* Allocate space for two buffer descriptors in the DP ram.
	 * For now, this address seems OK, but it may have to
	 * change with newer versions of the firmware.
	 * damm: allocating space after the two buffers for rx/tx data
	 */

	out_be32(&rtx->rxbd.cbd_bufaddr, (__force uint)&rtx->rxbuf);
	out_be16(&rtx->rxbd.cbd_sc, 0);

	out_be32(&rtx->txbd.cbd_bufaddr, (__force uint)&rtx->txbuf);
	out_be16(&rtx->txbd.cbd_sc, 0);

	/* Set up the uart parameters in the parameter ram. */
	out_be16(&up->smc_rbase, CPM_SERIAL_BASE);
	out_be16(&up->smc_tbase, CPM_SERIAL_BASE + sizeof(cbd_t));
	out_8(&up->smc_rfcr, SMC_EB);
	out_8(&up->smc_tfcr, SMC_EB);

	/* Set UART mode, 8 bit, no parity, one stop.
	 * Enable receive and transmit.
	 */
	out_be16(&sp->smc_smcmr, smcr_mk_clen(9) | SMCMR_SM_UART);

	/* Mask all interrupts and remove anything pending.
	*/
	out_8(&sp->smc_smcm, 0);
	out_8(&sp->smc_smce, 0xff);

	/* Set up the baud rate generator */
	serial_mpc8xx_setbrg(dev, gd->baudrate);

	/* Make the first buffer the only buffer. */
	setbits_be16(&rtx->txbd.cbd_sc, BD_SC_WRAP);
	setbits_be16(&rtx->rxbd.cbd_sc, BD_SC_EMPTY | BD_SC_WRAP);

	/* single/multi character receive. */
	out_be16(&up->smc_mrblr, CONFIG_SYS_SMC_RXBUFLEN);
	out_be16(&up->smc_maxidl, CONFIG_SYS_MAXIDLE);
	out_be32(&rtx->rxindex, 0);

	out_be32(&up->smc_rstate, 0);
	out_be32(&up->smc_tstate, 0);
	out_be16(&up->smc_rbptr, CPM_SERIAL_BASE);
	out_be16(&up->smc_tbptr, CPM_SERIAL_BASE + sizeof(cbd_t));
	out_be16(&up->smc_brkcr, 1);
	out_be16(&up->smc_brkec, 0);

	/* Enable transmitter/receiver.	*/
	setbits_be16(&sp->smc_smcmr, SMCMR_REN | SMCMR_TEN);

	return 0;
}

static int serial_mpc8xx_putc(struct udevice *dev, const char c)
{
	immap_t	__iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR;
	cpm8xx_t	__iomem *cpmp = &(im->im_cpm);
	struct serialbuffer	__iomem *rtx;

	rtx = (struct serialbuffer __iomem *)&cpmp->cp_dpmem[CPM_SERIAL_BASE];

	if (in_be16(&rtx->txbd.cbd_sc) & BD_SC_READY)
		return -EAGAIN;

	out_8(&rtx->txbuf, c);
	out_be16(&rtx->txbd.cbd_datlen, 1);
	setbits_be16(&rtx->txbd.cbd_sc, BD_SC_READY);

	return 0;
}

static int serial_mpc8xx_getc(struct udevice *dev)
{
	immap_t	__iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR;
	cpm8xx_t	__iomem *cpmp = &(im->im_cpm);
	struct serialbuffer	__iomem *rtx;
	unsigned char  c;
	uint rxindex;

	rtx = (struct serialbuffer __iomem *)&cpmp->cp_dpmem[CPM_SERIAL_BASE];

	if (in_be16(&rtx->rxbd.cbd_sc) & BD_SC_EMPTY)
		return -EAGAIN;

	/* the characters are read one by one,
	 * use the rxindex to know the next char to deliver
	 */
	rxindex = in_be32(&rtx->rxindex);
	c = in_8(rtx->rxbuf + rxindex);
	rxindex++;

	/* check if all char are readout, then make prepare for next receive */
	if (rxindex >= in_be16(&rtx->rxbd.cbd_datlen)) {
		rxindex = 0;
		setbits_be16(&rtx->rxbd.cbd_sc, BD_SC_EMPTY);
	}
	out_be32(&rtx->rxindex, rxindex);
	return c;
}

static int serial_mpc8xx_pending(struct udevice *dev, bool input)
{
	immap_t	__iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR;
	cpm8xx_t	__iomem *cpmp = &(im->im_cpm);
	struct serialbuffer	__iomem *rtx;

	if (!input)
		return 0;

	rtx = (struct serialbuffer __iomem *)&cpmp->cp_dpmem[CPM_SERIAL_BASE];

	return !(in_be16(&rtx->rxbd.cbd_sc) & BD_SC_EMPTY);
}

static const struct dm_serial_ops serial_mpc8xx_ops = {
	.putc = serial_mpc8xx_putc,
	.pending = serial_mpc8xx_pending,
	.getc = serial_mpc8xx_getc,
	.setbrg = serial_mpc8xx_setbrg,
};

static const struct udevice_id serial_mpc8xx_ids[] = {
	{ .compatible = "fsl,pq1-smc" },
	{ }
};

U_BOOT_DRIVER(serial_mpc8xx) = {
	.name	= "serial_mpc8xx",
	.id	= UCLASS_SERIAL,
	.of_match = serial_mpc8xx_ids,
	.probe = serial_mpc8xx_probe,
	.ops	= &serial_mpc8xx_ops,
	.flags = DM_FLAG_PRE_RELOC,
};
