/*
 * Copyright (c) 2013 Xilinx Inc.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <asm/io.h>
#include <malloc.h>
#include <asm/arch/hardware.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/clk.h>

#define SLCR_LOCK_MAGIC		0x767B
#define SLCR_UNLOCK_MAGIC	0xDF0D

#define SLCR_USB_L1_SEL			0x04

#define SLCR_IDCODE_MASK	0x1F000
#define SLCR_IDCODE_SHIFT	12

/*
 * zynq_slcr_mio_get_status - Get the status of MIO peripheral.
 *
 * @peri_name: Name of the peripheral for checking MIO status
 * @get_pins: Pointer to array of get pin for this peripheral
 * @num_pins: Number of pins for this peripheral
 * @mask: Mask value
 * @check_val: Required check value to get the status of  periph
 */
struct zynq_slcr_mio_get_status {
	const char *peri_name;
	const int *get_pins;
	int num_pins;
	u32 mask;
	u32 check_val;
};

static const int usb0_pins[] = {
	28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39
};

static const int usb1_pins[] = {
	40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
};

static const struct zynq_slcr_mio_get_status mio_periphs[] = {
	{
		"usb0",
		usb0_pins,
		ARRAY_SIZE(usb0_pins),
		SLCR_USB_L1_SEL,
		SLCR_USB_L1_SEL,
	},
	{
		"usb1",
		usb1_pins,
		ARRAY_SIZE(usb1_pins),
		SLCR_USB_L1_SEL,
		SLCR_USB_L1_SEL,
	},
};

static int slcr_lock = 1; /* 1 means locked, 0 means unlocked */

void zynq_slcr_lock(void)
{
	if (!slcr_lock) {
		writel(SLCR_LOCK_MAGIC, &slcr_base->slcr_lock);
		slcr_lock = 1;
	}
}

void zynq_slcr_unlock(void)
{
	if (slcr_lock) {
		writel(SLCR_UNLOCK_MAGIC, &slcr_base->slcr_unlock);
		slcr_lock = 0;
	}
}

/* Reset the entire system */
void zynq_slcr_cpu_reset(void)
{
	/*
	 * Unlock the SLCR then reset the system.
	 * Note that this seems to require raw i/o
	 * functions or there's a lockup?
	 */
	zynq_slcr_unlock();

	/*
	 * Clear 0x0F000000 bits of reboot status register to workaround
	 * the FSBL not loading the bitstream after soft-reboot
	 * This is a temporary solution until we know more.
	 */
	clrbits_le32(&slcr_base->reboot_status, 0xF000000);

	writel(1, &slcr_base->pss_rst_ctrl);
}

/* Setup clk for network */
void zynq_slcr_gem_clk_setup(u32 gem_id, unsigned long clk_rate)
{
	int ret;

	zynq_slcr_unlock();

	if (gem_id > 1) {
		printf("Non existing GEM id %d\n", gem_id);
		goto out;
	}

	ret = zynq_clk_set_rate(gem0_clk + gem_id, clk_rate);
	if (ret)
		goto out;

	if (gem_id) {
		/* Configure GEM_RCLK_CTRL */
		writel(1, &slcr_base->gem1_rclk_ctrl);
	} else {
		/* Configure GEM_RCLK_CTRL */
		writel(1, &slcr_base->gem0_rclk_ctrl);
	}
	udelay(100000);
out:
	zynq_slcr_lock();
}

void zynq_slcr_devcfg_disable(void)
{
	zynq_slcr_unlock();

	/* Disable AXI interface by asserting FPGA resets */
	writel(0xFFFFFFFF, &slcr_base->fpga_rst_ctrl);

	/* Set Level Shifters DT618760 */
	writel(0xA, &slcr_base->lvl_shftr_en);

	zynq_slcr_lock();
}

void zynq_slcr_devcfg_enable(void)
{
	zynq_slcr_unlock();

	/* Set Level Shifters DT618760 */
	writel(0xF, &slcr_base->lvl_shftr_en);

	/* Enable AXI interface by de-asserting FPGA resets */
	writel(0x0, &slcr_base->fpga_rst_ctrl);

	zynq_slcr_lock();
}

u32 zynq_slcr_get_boot_mode(void)
{
	/* Get the bootmode register value */
	return readl(&slcr_base->boot_mode);
}

u32 zynq_slcr_get_idcode(void)
{
	return (readl(&slcr_base->pss_idcode) & SLCR_IDCODE_MASK) >>
							SLCR_IDCODE_SHIFT;
}

/*
 * zynq_slcr_get_mio_pin_status - Get the MIO pin status of peripheral.
 *
 * @periph: Name of the peripheral
 *
 * Returns count to indicate the number of pins configured for the
 * given @periph.
 */
int zynq_slcr_get_mio_pin_status(const char *periph)
{
	const struct zynq_slcr_mio_get_status *mio_ptr;
	int val, i, j;
	int mio = 0;

	for (i = 0; i < ARRAY_SIZE(mio_periphs); i++) {
		if (strcmp(periph, mio_periphs[i].peri_name) == 0) {
			mio_ptr = &mio_periphs[i];
			for (j = 0; j < mio_ptr->num_pins; j++) {
				val = readl(&slcr_base->mio_pin
						[mio_ptr->get_pins[j]]);
				if ((val & mio_ptr->mask) == mio_ptr->check_val)
					mio++;
			}
			break;
		}
	}

	return mio;
}
