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

#include <common.h>

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

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

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)
{
	u32 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);
}

