/*
 * Copyright 2014 Google Inc.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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; either version 2 of
 * the License, or (at your option) any later version.
 *
 * 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., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <assert.h>
#include <stdint.h>

#include "base/algorithm.h"
#include "base/coreboot/sysinfo.h"
#include "base/init_funcs.h"
#include "boot/fit.h"
#include "drivers/blockdev/tegra_mmc.h"
#include "drivers/board/board.h"
#include "drivers/board/board_helpers.h"
#include "drivers/board/foster/coreboot.h"
#include "drivers/board/foster/foster.h"
#include "drivers/board/foster/panel.h"
#include "drivers/bus/i2c/tegra.h"
#include "drivers/bus/spi/tegra.h"
#include "drivers/bus/usb/usb.h"
#include "drivers/display/framebuffer.h"
#include "drivers/dma/tegra_apb.h"
#include "drivers/ec/cros/i2c.h"
#include "drivers/flash/spi.h"
#include "drivers/framebuffer/tegra132.h"
#include "drivers/gpio/fwdb.h"
#include "drivers/gpio/gpio.h"
#include "drivers/gpio/tegra.h"
#include "drivers/keyboard/dynamic.h"
#include "drivers/keyboard/pseudo/keyboard.h"
#include "drivers/power/gpio_reset.h"
#include "drivers/power/max77620.h"
#include "drivers/sound/i2s.h"
#include "drivers/sound/rt5677.h"
#include "drivers/sound/tegra_ahub.h"
#include "drivers/tpm/slb9635_i2c.h"
#include "drivers/tpm/tpm.h"
#include "drivers/uart/8250.h"

enum {
	CLK_RST_BASE = 0x60006000,

	CLK_RST_L_RST_SET = CLK_RST_BASE + 0x300,
	CLK_RST_L_RST_CLR = CLK_RST_BASE + 0x304,
	CLK_RST_H_RST_SET = CLK_RST_BASE + 0x308,
	CLK_RST_H_RST_CLR = CLK_RST_BASE + 0x30c,
	CLK_RST_U_RST_SET = CLK_RST_BASE + 0x310,
	CLK_RST_U_RST_CLR = CLK_RST_BASE + 0x314,
	CLK_RST_X_RST_SET = CLK_RST_BASE + 0x290,
	CLK_RST_X_RST_CLR = CLK_RST_BASE + 0x294
};

enum {
	CLK_L_I2C1 = 0x1 << 12,
	CLK_H_I2C2 = 0x1 << 22,
	CLK_U_I2C3 = 0x1 << 3,
	CLK_H_I2C5 = 0x1 << 15,
	CLK_X_I2C6 = 0x1 << 6
};

static void choose_devicetree_by_boardid(void)
{
	fit_set_compat("nvidia,foster");
}

static int no_tpm_xmit(struct TpmOps *me, const uint8_t *sendbuf,
		       size_t send_size, uint8_t *recvbuf, size_t *recv_len)
{
	return -1;
}

static TpmOps no_tpm_ops;

PRIV_DYN(pwr_i2c, &new_tegra_i2c((void *)0x7000d000, 5,
				 (void *)CLK_RST_H_RST_SET,
				 (void *)CLK_RST_H_RST_CLR,
				 CLK_H_I2C5)->ops)

PRIV_DYN(pmic, &new_max77620_pmic(get_pwr_i2c(), 0x3c)->ops)

PRIV_DYN(power_gpio, &new_tegra_gpio_input(GPIO(X, 5))->ops)

PUB_STAT(flag_option_roms_loaded, gpio_get(&fwdb_gpio_oprom.ops))
// Lid always open for now.
PUB_STAT(flag_lid_open, 1)
PUB_STAT(flag_power, !gpio_get(get_power_gpio()))

static TegraApbDmaController *build_dma_controller(void)
{
	void *dma_channel_bases[32];
	for (int i = 0; i < ARRAY_SIZE(dma_channel_bases); i++) {
		dma_channel_bases[i] =
			(void *)((uintptr_t)0x60021000 + 0x40 * i);
	}

	return new_tegra_apb_dma((void *)0x60020000, dma_channel_bases,
				 ARRAY_SIZE(dma_channel_bases));
}
PRIV_DYN(dma_controller, build_dma_controller())

PRIV_DYN(qspi, &new_tegra_spi(0x70410000, get_dma_controller(),
			      APBDMA_SLAVE_HSI)->ops)

PUB_DYN(_flash, &new_spi_flash(get_qspi())->ops);

static int board_setup(void)
{
	choose_devicetree_by_boardid();

	/* Foster has no TPM */
	no_tpm_ops.xmit = &no_tpm_xmit;
	tpm_set_ops(&no_tpm_ops);

	/* sdmmc4 */
	TegraMmcHost *emmc = new_tegra_mmc_host(0x700b0600, 8, 0, NULL, NULL);

	list_insert_after(&emmc->mmc.ctrlr.list_node,
			  &fixed_block_dev_controllers);

	/* sdmmc1: sd card */
	TegraGpio *enable_vdd_sd = new_tegra_gpio_output(GPIO(Z, 4));

	TegraGpio *card_detect = new_tegra_gpio_input(GPIO(Z, 1));
	GpioOps *card_detect_ops = &card_detect->ops;
	card_detect_ops = new_gpio_not(card_detect_ops);

	TegraMmcHost *sd_card = new_tegra_mmc_host(0x700b0000, 4, 1,
						   card_detect_ops,
						   &enable_vdd_sd->ops);

	list_insert_after(&sd_card->mmc.ctrlr.list_node,
			  &removable_block_dev_controllers);

	/* Careful: the EHCI base is at offset 0x100 from the SoC's IP base */
	UsbHostController *usbd = new_usb_hc(UsbEhci, 0x7d000100);

	list_insert_after(&usbd->list_node, &usb_host_controllers);

	/* Audio init */
	TegraAudioHubXbar *xbar = new_tegra_audio_hub_xbar(0x70300800);
	TegraAudioHubApbif *apbif = new_tegra_audio_hub_apbif(0x70300000, 8);
	TegraI2s *i2s1 = new_tegra_i2s(0x70301100, &apbif->ops, 1, 16, 2,
				       1536000, 48000);
	TegraAudioHub *ahub = new_tegra_audio_hub(xbar, apbif, i2s1);
	I2sSource *i2s_source = new_i2s_source(&i2s1->ops, 48000, 2, 16000);
	SoundRoute *sound_route = new_sound_route(&i2s_source->ops);
	TegraI2c *i2c6 = new_tegra_i2c((void *)0x7000d100, 6,
				       (void *)CLK_RST_X_RST_SET,
				       (void *)CLK_RST_X_RST_CLR,
				       CLK_X_I2C6);
	rt5677Codec *codec = new_rt5677_codec(&i2c6->ops, 0x2D, 16, 48000, 256, 1, 0);	//0x2C for P0
	list_insert_after(&ahub->component.list_node, &sound_route->components);
	list_insert_after(&codec->component.list_node, &sound_route->components);

	sound_set_ops(&sound_route->ops);

	return 0;
}

INIT_FUNC(board_setup);

PRIV_DYN(backlight_i2c, &new_tegra_i2c((void *)0x7000d100, 6,
				       (void *)CLK_RST_X_RST_SET,
				       (void *)CLK_RST_X_RST_CLR,
				       CLK_X_I2C6)->ops)

PRIV_DYN(panel, &new_foster_panel(get_backlight_i2c(), 0x2c)->ops)

PUB_DYN(_framebuffer, new_tegra132_framebuffer(0x54202000, 0x54201c00))
PUB_DYN(display, &new_fb_display(&board__framebuffer()->ops, get_panel())->ops)

PRIV_DYN(reset_gpio, new_tegra_gpio_output(GPIO(I, 5)));
PRIV_DYN(reset_gpio_n, new_gpio_not(&get_reset_gpio()->ops))

PUB_DYN(power, &new_gpio_reset_power_ops(get_pmic(), get_reset_gpio_n())->ops)

PUB_DYN(debug_uart, &new_uart_8250_mem32(0x70006000)->uart.ops)

PUB_ARR(trusted_keyboards, &pseudo_keyboard.ops);
PUB_ARR(untrusted_keyboards, &dynamic_keyboards.ops);
