/*
 * (C) Copyright 2010
 * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <command.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/ppc4xx-gpio.h>

#include <dtt.h>
#include <miiphy.h>

#include "405ep.h"
#include <gdsys_fpga.h>

#define LATCH0_BASE (CONFIG_SYS_LATCH_BASE)
#define LATCH1_BASE (CONFIG_SYS_LATCH_BASE + 0x100)
#define LATCH2_BASE (CONFIG_SYS_LATCH_BASE + 0x200)

#define PHYREG_CONTROL				0
#define PHYREG_PAGE_ADDRESS			22
#define PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1	16
#define PHYREG_PG2_COPPER_SPECIFIC_CONTROL_2	26

enum {
	UNITTYPE_CCD_SWITCH = 1,
};

enum {
	HWVER_100 = 0,
	HWVER_110 = 1,
	HWVER_121 = 2,
	HWVER_122 = 3,
};

struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR;

int misc_init_r(void)
{
	/* startup fans */
	dtt_init();

	return 0;
}

int configure_gbit_phy(unsigned char addr)
{
	unsigned short value;

	/* select page 2 */
	if (miiphy_write(CONFIG_SYS_GBIT_MII_BUSNAME, addr,
		PHYREG_PAGE_ADDRESS, 0x0002))
		goto err_out;
	/* disable SGMII autonegotiation */
	if (miiphy_write(CONFIG_SYS_GBIT_MII_BUSNAME, addr,
		PHYREG_PG2_COPPER_SPECIFIC_CONTROL_2, 0x800a))
		goto err_out;
	/* select page 0 */
	if (miiphy_write(CONFIG_SYS_GBIT_MII_BUSNAME, addr,
		PHYREG_PAGE_ADDRESS, 0x0000))
		goto err_out;
	/* switch from powerdown to normal operation */
	if (miiphy_read(CONFIG_SYS_GBIT_MII_BUSNAME, addr,
		PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1, &value))
		goto err_out;
	if (miiphy_write(CONFIG_SYS_GBIT_MII_BUSNAME, addr,
		PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1, value & ~0x0004))
		goto err_out;
	/* reset phy so settings take effect */
	if (miiphy_write(CONFIG_SYS_GBIT_MII_BUSNAME, addr,
		PHYREG_CONTROL, 0x9140))
		goto err_out;

	return 0;

err_out:
	printf("Error writing to the PHY addr=%02x\n", addr);
	return -1;
}

/*
 * Check Board Identity:
 */
int checkboard(void)
{
	char *s = getenv("serial#");

	puts("Board: CATCenter Io");

	if (s != NULL) {
		puts(", serial# ");
		puts(s);
	}

	puts("\n");

	return 0;
}

static void print_fpga_info(void)
{
	u16 versions;
	u16 fpga_version;
	u16 fpga_features;
	unsigned unit_type;
	unsigned hardware_version;
	unsigned feature_channels;
	unsigned feature_expansion;

	FPGA_GET_REG(0, versions, &versions);
	FPGA_GET_REG(0, fpga_version, &fpga_version);
	FPGA_GET_REG(0, fpga_features, &fpga_features);

	unit_type = (versions & 0xf000) >> 12;
	hardware_version = versions & 0x000f;
	feature_channels = fpga_features & 0x007f;
	feature_expansion = fpga_features & (1<<15);

	puts("FPGA:  ");

	switch (unit_type) {
	case UNITTYPE_CCD_SWITCH:
		printf("CCD-Switch");
		break;

	default:
		printf("UnitType %d(not supported)", unit_type);
		break;
	}

	switch (hardware_version) {
	case HWVER_100:
		printf(" HW-Ver 1.00\n");
		break;

	case HWVER_110:
		printf(" HW-Ver 1.10\n");
		break;

	case HWVER_121:
		printf(" HW-Ver 1.21\n");
		break;

	case HWVER_122:
		printf(" HW-Ver 1.22\n");
		break;

	default:
		printf(" HW-Ver %d(not supported)\n",
		       hardware_version);
		break;
	}

	printf("       FPGA V %d.%02d, features:",
		fpga_version / 100, fpga_version % 100);

	printf(" %d channel(s)", feature_channels);

	printf(", expansion %ssupported\n", feature_expansion ? "" : "un");
}

/*
 * setup Gbit PHYs
 */
int last_stage_init(void)
{
	unsigned int k;

	print_fpga_info();

	miiphy_register(CONFIG_SYS_GBIT_MII_BUSNAME,
		bb_miiphy_read, bb_miiphy_write);

	for (k = 0; k < 32; ++k)
		configure_gbit_phy(k);

	/* take fpga serdes blocks out of reset */
	FPGA_SET_REG(0, quad_serdes_reset, 0);

	return 0;
}

void gd405ep_init(void)
{
}

void gd405ep_set_fpga_reset(unsigned state)
{
	if (state) {
		out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_RESET);
		out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_RESET);
	} else {
		out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_BOOT);
		out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_BOOT);
	}
}

void gd405ep_setup_hw(void)
{
	/*
	 * set "startup-finished"-gpios
	 */
	gpio_write_bit(21, 0);
	gpio_write_bit(22, 1);
}

int gd405ep_get_fpga_done(unsigned fpga)
{
	return in_le16((void *)LATCH2_BASE) & CONFIG_SYS_FPGA_DONE(fpga);
}
