/* Copyright 2015 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <string.h>
#include <ipmi.h>
#include <time.h>
#include <time-utils.h>
#include <device.h>
#include <opal.h>
#include <rtc.h>
#include <lpc.h>
#include <lock.h>
#include <timebase.h>

/* Legacy RTC registers */
#define RTC_REG_SECONDS		0
#define RTC_REG_MINUTES		2
#define RTC_REG_HOURS		4
#define RTC_REG_DAY_OF_WEEK	6
#define RTC_REG_DAY_OF_MONTH	7
#define RTC_REG_MONTH		8
#define RTC_REG_YEAR		9
#define RTC_REG_A		10
#define   RTC_REG_A_UIP			0x80
#define RTC_REG_B		11
#define   RTC_REG_B_DIS_UPD		0x80
#define   RTC_REG_B_PIE			0x40
#define   RTC_REG_B_AIE			0x20
#define   RTC_REG_B_UIE			0x10
#define   RTC_REG_B_SQWE		0x08
#define   RTC_REG_B_DM_BINARY		0x04
#define   RTC_REG_B_24H			0x02
#define   RTC_REG_B_DST_EN		0x01
#define RTC_REG_C		12
#define RTC_REG_D		13
#define   RTC_REG_D_VALID		0x80

/* Init value is no interrupts, 24H mode, updates enabled */
#define RTC_REG_B_INIT		(RTC_REG_B_24H)

static u32 rtc_port;
static struct lock rtc_lock = LOCK_UNLOCKED;

static uint8_t rtc_read(uint8_t reg)
{
	lpc_outb(reg, rtc_port);
	return lpc_inb(rtc_port + 1);
}

static void rtc_write(uint8_t reg, uint8_t val)
{
	lpc_outb(reg, rtc_port);
	lpc_outb(val, rtc_port + 1);
}

static bool lpc_rtc_read_tm(struct tm *tm)
{
	struct tm tm2;
	unsigned int loops = 0;

	/* Read until two series provide identical values, this
	 * should deal with update races in all practical cases
	 */
	for (;;) {
		tm2 = *tm;
		tm->tm_sec = rtc_read(RTC_REG_SECONDS);
		tm->tm_min = rtc_read(RTC_REG_MINUTES);
		tm->tm_hour = rtc_read(RTC_REG_HOURS);
		tm->tm_mday = rtc_read(RTC_REG_DAY_OF_MONTH);
		tm->tm_mon = rtc_read(RTC_REG_MONTH);
		tm->tm_year = rtc_read(RTC_REG_YEAR);
		if (loops > 0 && memcmp(&tm2, tm, sizeof(struct tm)) == 0)
			break;
		loops++;
		if (loops > 10) {
			prerror("RTC: Failed to obtain stable values\n");
			return false;
		}
	}
	tm->tm_sec = bcd_byte(tm->tm_sec, 0);
	tm->tm_min = bcd_byte(tm->tm_min, 0);
	tm->tm_hour = bcd_byte(tm->tm_hour, 0);
	tm->tm_mday = bcd_byte(tm->tm_mday, 0);
	tm->tm_mon = bcd_byte(tm->tm_mon, 0) - 1;
	tm->tm_year = bcd_byte(tm->tm_year, 0);

	/* 2000 wrap */
	if (tm->tm_year < 69)
		tm->tm_year += 100;

	/* Base */
	tm->tm_year += 1900;

	return true;
}

static void lpc_rtc_write_tm(struct tm *tm __unused)
{
	/* XXX */
}

static void lpc_init_time(void)
{
	uint8_t val;
	struct tm tm;
	bool valid;

	memset(&tm, 0, sizeof(tm));

	lock(&rtc_lock);

	/* If update is in progress, wait a bit */
	val = rtc_read(RTC_REG_A);
	if (val & RTC_REG_A_UIP)
		time_wait_ms(10);

	/* Read from RTC */
	valid = lpc_rtc_read_tm(&tm);

	unlock(&rtc_lock);

	/* Update cache */
	if (valid)
		rtc_cache_update(&tm);
}

static void lpc_init_hw(void)
{
	lock(&rtc_lock);

	/* Set REG B to a suitable default */
	rtc_write(RTC_REG_B, RTC_REG_B_INIT);

	unlock(&rtc_lock);
}

static int64_t lpc_opal_rtc_read(uint32_t *y_m_d,
				 uint64_t *h_m_s_m)
{
	uint8_t val;
	int64_t rc = OPAL_SUCCESS;
	struct tm tm;

	if (!y_m_d || !h_m_s_m)
		return OPAL_PARAMETER;

	/* Return busy if updating. This is somewhat racy, but will
	 * do for now, most RTCs nowadays are smart enough to atomically
	 * update. Alternatively we could just read from the cache...
	 */
	lock(&rtc_lock);
	val = rtc_read(RTC_REG_A);
	if (val & RTC_REG_A_UIP) {
		unlock(&rtc_lock);
		return OPAL_BUSY_EVENT;
	}

	/* Read from RTC */
	if (lpc_rtc_read_tm(&tm))
		rc = OPAL_SUCCESS;
	else
		rc = OPAL_HARDWARE;
	unlock(&rtc_lock);

	if (rc == OPAL_SUCCESS) {
		/* Update cache */
		rtc_cache_update(&tm);

		/* Convert to OPAL time */
		tm_to_datetime(&tm, y_m_d, h_m_s_m);
	}

	return rc;
}

static int64_t lpc_opal_rtc_write(uint32_t year_month_day,
				  uint64_t hour_minute_second_millisecond)
{
	struct tm tm;

	/* Convert to struct tm */
	datetime_to_tm(year_month_day, hour_minute_second_millisecond, &tm);

	/* Write it out */
	lock(&rtc_lock);
	lpc_rtc_write_tm(&tm);
	unlock(&rtc_lock);

	return OPAL_SUCCESS;
}

void lpc_rtc_init(void)
{
	struct dt_node *rtc_node, *np;

	if (!lpc_present())
		return;

	/* We support only one */
	rtc_node = dt_find_compatible_node(dt_root, NULL, "pnpPNP,b00");
	if (!rtc_node)
		return;

	/* Get IO base */
	rtc_port = dt_prop_get_cell_def(rtc_node, "reg", 1, 0);
	if (!rtc_port) {
		prerror("RTC: Can't find reg property\n");
		return;
	}
	if (dt_prop_get_cell_def(rtc_node, "reg", 0, 0) != OPAL_LPC_IO) {
		prerror("RTC: Unsupported address type\n");
		return;
	}

	/* Init the HW */
	lpc_init_hw();

	/* Create OPAL API node and register OPAL calls */
	np = dt_new(opal_node, "rtc");
	dt_add_property_strings(np, "compatible", "ibm,opal-rtc");

	opal_register(OPAL_RTC_READ, lpc_opal_rtc_read, 2);
	opal_register(OPAL_RTC_WRITE, lpc_opal_rtc_write, 2);

	/* Initialise the rtc cache */
	lpc_init_time();
}
