/*
 * (C) Copyright 2009-2012 ADVANSEE
 * Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
 *
 * Based on the Linux rtc-imxdi.c driver, which is:
 * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
 * Copyright 2010 Orex Computed Radiography
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/*
 * Date & Time support for Freescale i.MX DryIce RTC
 */

#include <common.h>
#include <command.h>
#include <linux/compat.h>
#include <rtc.h>

#if defined(CONFIG_CMD_DATE)

#include <asm/io.h>
#include <asm/arch/imx-regs.h>

/* DryIce Register Definitions */

struct imxdi_regs {
	u32 dtcmr;			/* Time Counter MSB Reg */
	u32 dtclr;			/* Time Counter LSB Reg */
	u32 dcamr;			/* Clock Alarm MSB Reg */
	u32 dcalr;			/* Clock Alarm LSB Reg */
	u32 dcr;			/* Control Reg */
	u32 dsr;			/* Status Reg */
	u32 dier;			/* Interrupt Enable Reg */
};

#define DCAMR_UNSET	0xFFFFFFFF	/* doomsday - 1 sec */

#define DCR_TCE		(1 << 3)	/* Time Counter Enable */

#define DSR_WBF		(1 << 10)	/* Write Busy Flag */
#define DSR_WNF		(1 << 9)	/* Write Next Flag */
#define DSR_WCF		(1 << 8)	/* Write Complete Flag */
#define DSR_WEF		(1 << 7)	/* Write Error Flag */
#define DSR_CAF		(1 << 4)	/* Clock Alarm Flag */
#define DSR_NVF		(1 << 1)	/* Non-Valid Flag */
#define DSR_SVF		(1 << 0)	/* Security Violation Flag */

#define DIER_WNIE	(1 << 9)	/* Write Next Interrupt Enable */
#define DIER_WCIE	(1 << 8)	/* Write Complete Interrupt Enable */
#define DIER_WEIE	(1 << 7)	/* Write Error Interrupt Enable */
#define DIER_CAIE	(1 << 4)	/* Clock Alarm Interrupt Enable */

/* Driver Private Data */

struct imxdi_data {
	struct imxdi_regs __iomem	*regs;
	int				init_done;
};

static struct imxdi_data data;

/*
 * This function attempts to clear the dryice write-error flag.
 *
 * A dryice write error is similar to a bus fault and should not occur in
 * normal operation.  Clearing the flag requires another write, so the root
 * cause of the problem may need to be fixed before the flag can be cleared.
 */
static void clear_write_error(void)
{
	int cnt;

	puts("### Warning: RTC - Register write error!\n");

	/* clear the write error flag */
	__raw_writel(DSR_WEF, &data.regs->dsr);

	/* wait for it to take effect */
	for (cnt = 0; cnt < 1000; cnt++) {
		if ((__raw_readl(&data.regs->dsr) & DSR_WEF) == 0)
			return;
		udelay(10);
	}
	puts("### Error: RTC - Cannot clear write-error flag!\n");
}

/*
 * Write a dryice register and wait until it completes.
 *
 * Use interrupt flags to determine when the write has completed.
 */
#define DI_WRITE_WAIT(val, reg)						\
(									\
	/* do the register write */					\
	__raw_writel((val), &data.regs->reg),				\
									\
	di_write_wait((val), #reg)					\
)
static int di_write_wait(u32 val, const char *reg)
{
	int cnt;
	int ret = 0;
	int rc = 0;

	/* wait for the write to finish */
	for (cnt = 0; cnt < 100; cnt++) {
		if ((__raw_readl(&data.regs->dsr) & (DSR_WCF | DSR_WEF)) != 0) {
			ret = 1;
			break;
		}
		udelay(10);
	}
	if (ret == 0)
		printf("### Warning: RTC - Write-wait timeout "
				"val = 0x%.8x reg = %s\n", val, reg);

	/* check for write error */
	if (__raw_readl(&data.regs->dsr) & DSR_WEF) {
		clear_write_error();
		rc = -1;
	}

	return rc;
}

/*
 * Initialize dryice hardware
 */
static int di_init(void)
{
	int rc = 0;

	data.regs = (struct imxdi_regs __iomem *)IMX_DRYICE_BASE;

	/* mask all interrupts */
	__raw_writel(0, &data.regs->dier);

	/* put dryice into valid state */
	if (__raw_readl(&data.regs->dsr) & DSR_NVF) {
		rc = DI_WRITE_WAIT(DSR_NVF | DSR_SVF, dsr);
		if (rc)
			goto err;
	}

	/* initialize alarm */
	rc = DI_WRITE_WAIT(DCAMR_UNSET, dcamr);
	if (rc)
		goto err;
	rc = DI_WRITE_WAIT(0, dcalr);
	if (rc)
		goto err;

	/* clear alarm flag */
	if (__raw_readl(&data.regs->dsr) & DSR_CAF) {
		rc = DI_WRITE_WAIT(DSR_CAF, dsr);
		if (rc)
			goto err;
	}

	/* the timer won't count if it has never been written to */
	if (__raw_readl(&data.regs->dtcmr) == 0) {
		rc = DI_WRITE_WAIT(0, dtcmr);
		if (rc)
			goto err;
	}

	/* start keeping time */
	if (!(__raw_readl(&data.regs->dcr) & DCR_TCE)) {
		rc = DI_WRITE_WAIT(__raw_readl(&data.regs->dcr) | DCR_TCE, dcr);
		if (rc)
			goto err;
	}

	data.init_done = 1;
	return 0;

err:
	return rc;
}

int rtc_get(struct rtc_time *tmp)
{
	unsigned long now;
	int rc = 0;

	if (!data.init_done) {
		rc = di_init();
		if (rc)
			goto err;
	}

	now = __raw_readl(&data.regs->dtcmr);
	to_tm(now, tmp);

err:
	return rc;
}

int rtc_set(struct rtc_time *tmp)
{
	unsigned long now;
	int rc;

	if (!data.init_done) {
		rc = di_init();
		if (rc)
			goto err;
	}

	now = mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
		     tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
	/* zero the fractional part first */
	rc = DI_WRITE_WAIT(0, dtclr);
	if (rc == 0)
		rc = DI_WRITE_WAIT(now, dtcmr);

err:
	return rc;
}

void rtc_reset(void)
{
	di_init();
}

#endif
