/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2014 Imagination Technologies
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of
 * the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
 * MA 02110-1301 USA
 */

#include <arch/io.h>
#include <stdint.h>
#include <soc/clocks.h>
#include <assert.h>
#include <boardid.h>

#define PADS_FUNCTION_SELECT0_ADDR	(0xB8101C00 + 0xC0)

#define GPIO_BIT_EN_ADDR(bank)		(0xB8101C00 + 0x200 + (0x24 * (bank)))
#define PAD_DRIVE_STRENGTH_ADDR(bank)	(0xB8101C00 + 0x120 + (0x4 * (bank)))
#define MAX_NO_MFIOS				89
#define PAD_DRIVE_STRENGTH_LENGTH		2
#define PAD_DRIVE_STRENGTH_MASK			0x3

typedef enum {
	DRIVE_STRENGTH_2mA      = 0,
	DRIVE_STRENGTH_4mA      = 1,
	DRIVE_STRENGTH_8mA      = 2,
	DRIVE_STRENGTH_12mA     = 3
} drive_strength;

/* MFIO definitions for UART1 */
#define UART1_RXD_MFIO			59
#define UART1_TXD_MFIO			60

/* MFIO definitions for SPIM */
#define SPIM1_D0_TXD_MFIO		5
#define SPIM1_D1_RXD_MFIO		4
#define SPIM1_MCLK_MFIO			3
#define SPIM1_D2_MFIO			6
#define SPIM1_D3_MFIO			7
#define SPIM1_CS0_MFIO			0

/* MFIO definitions for I2C */
#define I2C_DATA_MFIO(i)		(28 + (2*(i)))
#define I2C_CLK_MFIO(i)			(29 + (2*(i)))
#define I2C_DATA_FUNCTION_OFFSET(i)	(20 + (2*(i)))
#define I2C_CLK_FUNCTION_OFFSET(i)	(21 + (2*(i)))
#define I2C_DATA_FUNCTION_MASK		0x1
#define I2C_CLK_FUNCTION_MASK		0x1

static void pad_drive_strength(u32 pad, drive_strength strength)
{
	u32 reg, drive_strength_shift;

	assert(pad <= MAX_NO_MFIOS);
	assert(!(strength & ~(PAD_DRIVE_STRENGTH_MASK)));

	/* Set drive strength value */
	drive_strength_shift = (pad % 16) * PAD_DRIVE_STRENGTH_LENGTH;
	reg = read32(PAD_DRIVE_STRENGTH_ADDR(pad / 16));
	reg &= ~(PAD_DRIVE_STRENGTH_MASK << drive_strength_shift);
	reg |= strength << drive_strength_shift;
	write32(PAD_DRIVE_STRENGTH_ADDR(pad / 16), reg);
}

static void uart1_mfio_setup(void)
{
	u32 reg, mfio_mask;

	/*
	 * Disable GPIO for UART1 MFIOs
	 * All UART MFIOs have MFIO/16 = 3, therefore we use GPIO pad 3
	 * This is the only function (0) of these MFIOs and therfore there
	 * is no need to set up a function number in the corresponding
	 * function select register.
	 */
	reg = read32(GPIO_BIT_EN_ADDR(3));
	mfio_mask =  1 << (UART1_RXD_MFIO % 16);
	mfio_mask |= 1 << (UART1_TXD_MFIO % 16);
	/* Clear relevant bits */
	reg &= ~mfio_mask;
	/*
	 * Set corresponding bits in the upper half word
	 * in order to be able to modify the chosen pins
	 */
	reg |= mfio_mask << 16;
	write32(GPIO_BIT_EN_ADDR(3), reg);
}

static void spim1_mfio_setup(void)
{
	u32 reg, mfio_mask;
	/*
	 * Disable GPIO for SPIM1 MFIOs
	 * All SPFI1 MFIOs have MFIO/16 = 0, therefore we use GPIO pad 0
	 * This is the only function (0) of these MFIOs and therfore there
	 * is no need to set up a function number in the corresponding
	 * function select register.
	 */
	reg = read32(GPIO_BIT_EN_ADDR(0));

	/* Disable GPIO for SPIM1 MFIOs */
	mfio_mask = 1 << (SPIM1_D0_TXD_MFIO % 16);
	mfio_mask |= 1 << (SPIM1_D1_RXD_MFIO % 16);
	mfio_mask |= 1 << (SPIM1_MCLK_MFIO % 16);
	mfio_mask |= 1 << (SPIM1_D2_MFIO % 16);
	mfio_mask |= 1 << (SPIM1_D3_MFIO % 16);
	mfio_mask |= 1 << (SPIM1_CS0_MFIO % 16);

	/* Clear relevant bits */
	reg &= ~mfio_mask;
	/*
	 * Set corresponding bits in the upper half word
	 * in order to be able to modify the chosen pins
	 */
	reg |= mfio_mask << 16;
	write32(GPIO_BIT_EN_ADDR(0), reg);

	/* Set drive strength to maximum for these MFIOs */
	pad_drive_strength(SPIM1_CS0_MFIO, DRIVE_STRENGTH_12mA);
	pad_drive_strength(SPIM1_D1_RXD_MFIO, DRIVE_STRENGTH_12mA);
	pad_drive_strength(SPIM1_D0_TXD_MFIO, DRIVE_STRENGTH_12mA);
	pad_drive_strength(SPIM1_D2_MFIO, DRIVE_STRENGTH_12mA);
	pad_drive_strength(SPIM1_D3_MFIO, DRIVE_STRENGTH_12mA);
	pad_drive_strength(SPIM1_MCLK_MFIO, DRIVE_STRENGTH_12mA);
}

static void i2c_mfio_setup(int interface)
{
	u32 reg, mfio_mask;

	assert(interface < 4);
	/*
	 * Disable GPIO for I2C MFIOs
	 */
	reg = read32(GPIO_BIT_EN_ADDR(I2C_DATA_MFIO(interface) / 16));
	mfio_mask =  1 << (I2C_DATA_MFIO(interface) % 16);
	mfio_mask |= 1 << (I2C_CLK_MFIO(interface) % 16);
	/* Clear relevant bits */
	reg &= ~mfio_mask;
	/*
	 * Set corresponding bits in the upper half word
	 * in order to be able to modify the chosen pins
	 */
	reg |= mfio_mask << 16;
	write32(GPIO_BIT_EN_ADDR(I2C_DATA_MFIO(interface) / 16), reg);

	/* for I2C0 and I2C1:
	 * Set bits to 0 (clear) which is the primary function
	 * for these MFIOs; those bits will all be set to 1 by
	 * default.
	 * There is no need to do that for I2C2 and I2C3
	 */
	if (interface > 1)
		return;
	reg = read32(PADS_FUNCTION_SELECT0_ADDR);
	reg &= ~(I2C_DATA_FUNCTION_MASK <<
		I2C_DATA_FUNCTION_OFFSET(interface));
	reg &= ~(I2C_CLK_FUNCTION_MASK <<
		I2C_CLK_FUNCTION_OFFSET(interface));
	write32(PADS_FUNCTION_SELECT0_ADDR, reg);
}

static void bootblock_mainboard_init(void)
{
	int ret;

	/* System PLL divided by 2 -> 400 MHz */
	/* The same frequency will be the input frequency for the SPFI block */
	system_clk_setup(1);

	/* MIPS CPU dividers: division by 1 -> 546 MHz
	 * This is set up as we cannot make any assumption about
	 * the values set or not by the boot ROM code */
	mips_clk_setup(0, 0);

	/* Setup system PLL at 800 MHz */
	ret = sys_pll_setup(2, 1);
	if (ret != CLOCKS_OK)
		return;
	/* Setup MIPS PLL at 546 MHz */
	ret = mips_pll_setup(2, 1, 1, 21);
	if (ret != CLOCKS_OK)
		return;

	/* Setup SPIM1 MFIOs */
	spim1_mfio_setup();
	/* Setup UART1 clock and MFIOs
	 * System PLL divided by 7 divided by 62 -> 1.8433 Mhz
	 */
	uart1_clk_setup(6, 61);
	uart1_mfio_setup();
}


static int init_extra_hardware(void)
{
	const struct board_hw *hardware;

	/* Obtain information about current board */
	hardware = board_get_hw();
	if (!hardware) {
		printk(BIOS_ERR, "%s: Invalid hardware information.\n",
			__func__);
		return -1;
	}

	/* Setup USB clock
	 * System clock divided by 8 -> 50 MHz
	 */
	if (usb_clk_setup(7, 2, 7) != CLOCKS_OK) {
		printk(BIOS_ERR, "%s: Failed to set up USB clock.\n",
			__func__);
		return -1;
	}

	/* Setup I2C clocks and MFIOs
	 * System PLL divided by 4 divided by 3 -> 33.33 MHz
	 */
	i2c_clk_setup(3, 2, hardware->i2c_interface);
	i2c_mfio_setup(hardware->i2c_interface);

	/* Ethernet clocks setup: ENET as clock source */
	eth_clk_setup(0, 7);
	/* ROM clock setup: system clock divided by 2 -> 200 MHz */
	/* Hash accelerator is driven from the ROM clock */
	rom_clk_setup(1);

	return 0;
}
