/* Copyright 2013-2014 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 <skiboot.h>
#include <device.h>
#include <lpc.h>
#include <console.h>
#include <opal.h>
#include <interrupts.h>
#include <libflash/libflash.h>
#include <libflash/libffs.h>
#include <libflash/blocklevel.h>
#include <sfc-ctrl.h>
#include <ec/config.h>
#include <ec/gpio.h>

/*
 * EC GPIO mapping
 */
#define RHESUS_RST_UCD90160_N	EC_GPIO_PORT_J, 3
#define RHESUS_FM_PWR_CYCLE_N	EC_GPIO_PORT_K, 2
#define RHESUS_EN_PWR_ON_SEQ	EC_GPIO_PORT_R, 1
#define RHESUS_BOARD_REVISION0	EC_GPIO_PORT_F, 3
#define RHESUS_BOARD_REVISION1	EC_GPIO_PORT_F, 2
#define RHESUS_BOARD_REVISION2	EC_GPIO_PORT_E, 5
#define RHESUS_BOARD_REVISION3	EC_GPIO_PORT_E, 4
#define RHESUS_BOARD_REVISION4	EC_GPIO_PORT_E, 1


/*
 * IO accessors for the EC driver
 */
void ec_outb(uint16_t addr, uint8_t data)
{
	lpc_outb(data, addr);
}

uint8_t ec_inb(uint16_t addr)
{
	return lpc_inb(addr);
}

static int rhesus_board_revision(void)
{
    int revision = 0, ret = 0, i = 0;

    static const struct {
        EcGpioPort port;
        uint8_t pin;
    } revision_gpios[] = {
        { RHESUS_BOARD_REVISION0 },
        { RHESUS_BOARD_REVISION1 },
        { RHESUS_BOARD_REVISION2 },
        { RHESUS_BOARD_REVISION3 },
        { RHESUS_BOARD_REVISION4 },
    };
    for (i = 0; i < sizeof(revision_gpios) / sizeof(revision_gpios[0]); ++i)
    {
        ret = ec_gpio_read(revision_gpios[i].port, revision_gpios[i].pin);
        if (ret < 0)
            return ret;
        revision <<= 1; revision |= ret;
    }

    return revision;
}

static int64_t rhesus_reboot(void)
{
    // TODO(rlippert): This should use EC_SYS_RST_N, but there is nothing to
    // deassert that at the moment.
    int ret = 0;
    ret = ec_gpio_set(RHESUS_FM_PWR_CYCLE_N, 0);
    if (ret < 0) {
        return ret;
    }

    ret = ec_gpio_setup(RHESUS_FM_PWR_CYCLE_N,
                        EC_GPIO_OUTPUT,
                        EC_GPIO_PULLUP_DISABLE);
    if (ret < 0) {
        return ret;
    }

    return 0;
}

static int64_t rhesus_power_down(uint64_t request __unused)
{
    int ret = 0;
    ret = ec_gpio_set(RHESUS_EN_PWR_ON_SEQ, 0);
    if (ret < 0) {
        return ret;
    }

    ret = ec_gpio_setup(RHESUS_EN_PWR_ON_SEQ,
                        EC_GPIO_OUTPUT,
                        EC_GPIO_PULLUP_DISABLE);
    if (ret < 0) {
        return ret;
    }

    return 0;
}

static int rhesus_pnor_init(void)
{
	struct spi_flash_ctrl *pnor_ctrl;
	struct blocklevel_device *bl = NULL;
	int rc;

	/* Open controller, flash and ffs */
	rc = sfc_open(&pnor_ctrl);
	if (rc) {
		prerror("PLAT: Failed to open PNOR flash controller\n");
		goto fail;
	}
	rc = flash_init(pnor_ctrl, &bl, NULL);
	if (rc) {
		prerror("PLAT: Failed to open init PNOR driver\n");
		goto fail;
	}

	rc = flash_register(bl);
	if (!rc)
		return 0;

 fail:
	if (bl)
		flash_exit(bl);
	if (pnor_ctrl)
		sfc_close(pnor_ctrl);

	return rc;
}

static void rhesus_init(void)
{
	/* Initialize PNOR/NVRAM */
	rhesus_pnor_init();

	/* Setup UART for direct use by Linux */
	uart_setup_linux_passthrough();
}

static void rhesus_dt_fixup_uart(struct dt_node *lpc, bool has_irq)
{
	/*
	 * The official OF ISA/LPC binding is a bit odd, it prefixes
	 * the unit address for IO with "i". It uses 2 cells, the first
	 * one indicating IO vs. Memory space (along with bits to
	 * represent aliasing).
	 *
	 * We pickup that binding and add to it "2" as a indication
	 * of FW space.
	 *
	 * TODO: Probe the UART instead if the LPC bus allows for it
	 */
	struct dt_node *uart;
	char namebuf[32];
#define UART_IO_BASE	0x3f8
#define UART_IO_COUNT	8

	snprintf(namebuf, sizeof(namebuf), "serial@i%x", UART_IO_BASE);
	uart = dt_new(lpc, namebuf);

	dt_add_property_cells(uart, "reg",
			      1, /* IO space */
			      UART_IO_BASE, UART_IO_COUNT);
	dt_add_property_strings(uart, "compatible",
				"ns16550",
				"pnpPNP,501");
	dt_add_property_cells(uart, "clock-frequency", 1843200);
	dt_add_property_cells(uart, "current-speed", 115200);

	/*
	 * This is needed by Linux for some obscure reasons,
	 * we'll eventually need to sanitize it but in the meantime
	 * let's make sure it's there
	 */
	dt_add_property_strings(uart, "device_type", "serial");

	/* Expose the external interrupt if supported
	 */
	if (has_irq) {
		uint32_t chip_id = dt_get_chip_id(lpc);
		uint32_t irq = get_psi_interrupt(chip_id) + P8_IRQ_PSI_EXTERNAL;
		dt_add_property_cells(uart, "interrupts", irq, 1);
		dt_add_property_cells(uart, "interrupt-parent",
				      get_ics_phandle());
	}
}

/*
 * This adds the legacy RTC device to the device-tree
 * for Linux to use
 */
static void rhesus_dt_fixup_rtc(struct dt_node *lpc)
{
	struct dt_node *rtc;

	/*
	 * Follows the structure expected by the kernel file
	 * arch/powerpc/sysdev/rtc_cmos_setup.c
	 */
	rtc = dt_new_addr(lpc, "rtc", EC_RTC_PORT_BASE);
	assert(rtc);
	dt_add_property_string(rtc, "compatible", "pnpPNP,b00");
	dt_add_property_cells(rtc, "reg",
			      1, /* IO space */
			      EC_RTC_PORT_BASE,
			      /* 1 index/data pair per 128 bytes */
			      (EC_RTC_BLOCK_SIZE / 128) * 2);
}

static void rhesus_dt_fixup(bool has_uart_irq)
{
	struct dt_node *n, *primary_lpc = NULL;

	/* Find the primary LPC bus */
	dt_for_each_compatible(dt_root, n, "ibm,power8-lpc") {
		if (!primary_lpc || dt_has_node_property(n, "primary", NULL))
			primary_lpc = n;
		if (dt_has_node_property(n, "#address-cells", NULL))
			break;
	}

	if (!primary_lpc)
		return;

	rhesus_dt_fixup_rtc(primary_lpc);
	rhesus_dt_fixup_uart(primary_lpc, has_uart_irq);
}

static bool rhesus_probe(void)
{
	const char *model;
	int rev;
	bool has_uart_irq = false;

	if (!dt_node_is_compatible(dt_root, "ibm,powernv"))
		return false;

	model = dt_prop_get_def(dt_root, "model", NULL);
	if (!model || !(strstr(model, "rhesus") || strstr(model, "RHESUS")))
		return false;

	/* Grab board version from EC */
	rev = rhesus_board_revision();
	if (rev >= 0) {
		printf("Rhesus board rev %d\n", rev);
		dt_add_property_cells(dt_root, "revision-id", rev);
	} else
		prerror("Rhesus board revision not found !\n");

	/* Add missing bits of device-tree such as the UART */
	rhesus_dt_fixup(has_uart_irq);

	/* Setup UART and use it as console */
	uart_init();

	return true;
}

DECLARE_PLATFORM(rhesus) = {
	.name		= "Rhesus",
	.probe		= rhesus_probe,
	.init		= rhesus_init,
	.cec_power_down	= rhesus_power_down,
	.cec_reboot	= rhesus_reboot,
};
