// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2013 Keymile AG
 * Valentin Longchamp <valentin.longchamp@keymile.com>
 */

#include <common.h>
#include <asm/io.h>
#include <linux/bitops.h>

#include "common.h"
#include "qrio.h"

/* QRIO ID register offset */
#define ID_REV_OFF		0x00

/* QRIO GPIO register offsets */
#define DIRECT_OFF		0x18
#define GPRT_OFF		0x1c

void show_qrio(void)
{
	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
	u16 id_rev = in_be16(qrio_base + ID_REV_OFF);

	printf("QRIO: id = %u, revision = %u\n",
	       (id_rev >> 8) & 0xff, id_rev & 0xff);
}

int qrio_get_gpio(u8 port_off, u8 gpio_nr)
{
	u32 gprt;

	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;

	gprt = in_be32(qrio_base + port_off + GPRT_OFF);

	return (gprt >> gpio_nr) & 1U;
}

void qrio_set_gpio(u8 port_off, u8 gpio_nr, bool value)
{
	u32 gprt, mask;

	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;

	mask = 1U << gpio_nr;

	gprt = in_be32(qrio_base + port_off + GPRT_OFF);
	if (value)
		gprt |= mask;
	else
		gprt &= ~mask;

	out_be32(qrio_base + port_off + GPRT_OFF, gprt);
}

void qrio_gpio_direction_output(u8 port_off, u8 gpio_nr, bool value)
{
	u32 direct, mask;

	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;

	mask = 1U << gpio_nr;

	direct = in_be32(qrio_base + port_off + DIRECT_OFF);
	direct |= mask;
	out_be32(qrio_base + port_off + DIRECT_OFF, direct);

	qrio_set_gpio(port_off, gpio_nr, value);
}

void qrio_gpio_direction_input(u8 port_off, u8 gpio_nr)
{
	u32 direct, mask;

	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;

	mask = 1U << gpio_nr;

	direct = in_be32(qrio_base + port_off + DIRECT_OFF);
	direct &= ~mask;
	out_be32(qrio_base + port_off + DIRECT_OFF, direct);
}

void qrio_set_opendrain_gpio(u8 port_off, u8 gpio_nr, u8 val)
{
	u32 direct, mask;

	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;

	mask = 1U << gpio_nr;

	direct = in_be32(qrio_base + port_off + DIRECT_OFF);
	if (val == 0)
		/* set to output -> GPIO drives low */
		direct |= mask;
	else
		/* set to input -> GPIO floating */
		direct &= ~mask;

	out_be32(qrio_base + port_off + DIRECT_OFF, direct);
}

#define WDMASK_OFF	0x16

void qrio_wdmask(u8 bit, bool wden)
{
	u16 wdmask;
	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;

	wdmask = in_be16(qrio_base + WDMASK_OFF);

	if (wden)
		wdmask |= (1 << bit);
	else
		wdmask &= ~(1 << bit);

	out_be16(qrio_base + WDMASK_OFF, wdmask);
}

#define PRST_OFF	0x1a

void qrio_prst(u8 bit, bool en, bool wden)
{
	u16 prst;
	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;

	qrio_wdmask(bit, wden);

	prst = in_be16(qrio_base + PRST_OFF);

	if (en)
		prst &= ~(1 << bit);
	else
		prst |= (1 << bit);

	out_be16(qrio_base + PRST_OFF, prst);
}

#define PRSTCFG_OFF	0x1c

void qrio_prstcfg(u8 bit, u8 mode)
{
	unsigned long prstcfg;
	u8 i;
	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;

	prstcfg = in_be32(qrio_base + PRSTCFG_OFF);

	for (i = 0; i < 2; i++) {
		if (mode & (1 << i))
			__set_bit(2 * bit + i, &prstcfg);
		else
			__clear_bit(2 * bit + i, &prstcfg);
	}

	out_be32(qrio_base + PRSTCFG_OFF, prstcfg);
}

#define CTRLH_OFF		0x02
#define CTRLH_WRL_BOOT		0x01
#define CTRLH_WRL_UNITRUN	0x02

void qrio_set_leds(void)
{
	u8 ctrlh;
	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;

	/* set UNIT LED to RED and BOOT LED to ON */
	ctrlh = in_8(qrio_base + CTRLH_OFF);
	ctrlh |= (CTRLH_WRL_BOOT | CTRLH_WRL_UNITRUN);
	out_8(qrio_base + CTRLH_OFF, ctrlh);
}

#define CTRLL_OFF		0x03
#define CTRLL_WRB_BUFENA	0x20

void qrio_enable_app_buffer(void)
{
	u8 ctrll;
	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;

	/* enable application buffer */
	ctrll = in_8(qrio_base + CTRLL_OFF);
	ctrll |= (CTRLL_WRB_BUFENA);
	out_8(qrio_base + CTRLL_OFF, ctrll);
}

#define REASON1_OFF	0x12
#define REASON1_CPUWD	0x01

void qrio_cpuwd_flag(bool flag)
{
	u8 reason1;
	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;

	reason1 = in_8(qrio_base + REASON1_OFF);
	if (flag)
		reason1 |= REASON1_CPUWD;
	else
		reason1 &= ~REASON1_CPUWD;
	out_8(qrio_base + REASON1_OFF, reason1);
}

#define REASON0_OFF	0x13
#define REASON0_SWURST	0x80
#define REASON0_CPURST	0x40
#define REASON0_BPRST	0x20
#define REASON0_COPRST	0x10
#define REASON0_SWCRST	0x08
#define REASON0_WDRST	0x04
#define REASON0_KBRST	0x02
#define REASON0_POWUP	0x01
#define UNIT_RESET\
	(REASON0_POWUP | REASON0_COPRST | REASON0_KBRST |\
	 REASON0_BPRST | REASON0_SWURST | REASON0_WDRST)
#define CORE_RESET      ((REASON1_CPUWD << 8) | REASON0_SWCRST)

bool qrio_reason_unitrst(void)
{
	u16 reason;
	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;

	reason = in_be16(qrio_base + REASON1_OFF);

	return (reason & UNIT_RESET) > 0;
}

#define RSTCFG_OFF	0x11

void qrio_uprstreq(u8 mode)
{
	u32 rstcfg;
	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;

	rstcfg = in_8(qrio_base + RSTCFG_OFF);

	if (mode & UPREQ_CORE_RST)
		rstcfg |= UPREQ_CORE_RST;
	else
		rstcfg &= ~UPREQ_CORE_RST;

	out_8(qrio_base + RSTCFG_OFF, rstcfg);
}

/* I2C deblocking uses the algorithm defined in board/keymile/common/common.c
 * 2 dedicated QRIO GPIOs externally pull the SCL and SDA lines
 * For I2C only the low state is activly driven and high state is pulled-up
 * by a resistor. Therefore the deblock GPIOs are used
 *  -> as an active output to drive a low state
 *  -> as an open-drain input to have a pulled-up high state
 */

/* By default deblock GPIOs are floating */
void i2c_deblock_gpio_cfg(void)
{
	/* set I2C bus 1 deblocking GPIOs input, but 0 value for open drain */
	qrio_gpio_direction_input(KM_I2C_DEBLOCK_PORT,
				  KM_I2C_DEBLOCK_SCL);
	qrio_gpio_direction_input(KM_I2C_DEBLOCK_PORT,
				  KM_I2C_DEBLOCK_SDA);

	qrio_set_gpio(KM_I2C_DEBLOCK_PORT,
		      KM_I2C_DEBLOCK_SCL, 0);
	qrio_set_gpio(KM_I2C_DEBLOCK_PORT,
		      KM_I2C_DEBLOCK_SDA, 0);
}

void set_sda(int state)
{
	qrio_set_opendrain_gpio(KM_I2C_DEBLOCK_PORT,
				KM_I2C_DEBLOCK_SDA, state);
}

void set_scl(int state)
{
	qrio_set_opendrain_gpio(KM_I2C_DEBLOCK_PORT,
				KM_I2C_DEBLOCK_SCL, state);
}

int get_sda(void)
{
	return qrio_get_gpio(KM_I2C_DEBLOCK_PORT,
			     KM_I2C_DEBLOCK_SDA);
}

int get_scl(void)
{
	return qrio_get_gpio(KM_I2C_DEBLOCK_PORT,
			     KM_I2C_DEBLOCK_SCL);
}
