/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2014 Siemens AG
 *
 * 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.
 */

#include <console/console.h>
#include <hwilib.h>
#include <string.h>
#include "soc/i2c.h"
#include "ptn3460.h"

/** \brief This functions sets up the DP2LVDS-converter to be used with the
 *         appropriate lcd panel
 * @param  *hwi_block	Filename in CBFS of the block to use as HW-Info
 * @return		0 on success or error code
 */
int ptn3460_init(char *hwi_block)
{
	struct ptn_3460_config cfg;
	int status;
	uint8_t disp_con = 0, color_depth = 0;
	uint8_t edid_data[0x80];
	uint8_t hwid[4], tcu31_hwid[4] = {7, 9, 2, 0};

	if (!hwi_block || hwilib_find_blocks(hwi_block) != CB_SUCCESS) {
		printk(BIOS_ERR, "LCD: Info block \"%s\" not found!\n",
			hwi_block);
		return 1;
	}

	status = i2c_init(PTN_I2C_CONTROLER);
	if (status)
		return (PTN_BUS_ERROR | status);

	/* Get all needed information from hwinfo block */
	if (hwilib_get_field(Edid, edid_data, 0x80) != sizeof(edid_data)) {
		printk(BIOS_ERR, "LCD: No EDID data available in %s\n",
			hwi_block);
		return 1;
	}
	if ((hwilib_get_field(PF_DisplCon, &disp_con, 1) != 1)) {
		printk(BIOS_ERR, "LCD: Missing panel features from %s\n",
			hwi_block);
		return 1;
	}
	if (hwilib_get_field(PF_Color_Depth ,&color_depth, 1) != 1) {
		printk(BIOS_ERR, "LCD: Missing panel features from %s\n",
			hwi_block);
		return 1;
	}
	/* Here, all the desired information for setting up DP2LVDS converter*/
	/* are present. Inside the converter, table 6 will be used for */
	/* the timings. */
	if ((status = ptn3460_write_edid(6, edid_data)) != 0)
		return status;
	/* Select this table to be emulated */
	ptn_select_edid(6);
	/* Read PTN configuration data */
	status = i2c_read(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_CONFIG_OFF,
			  (u8*)&cfg, PTN_CONFIG_LEN);
	if (status)
		return (PTN_BUS_ERROR | status);

	/* Set up configuration data according to the hwinfo blocks we get */
	cfg.dp_interface_ctrl = 0;
	cfg.lvds_interface_ctrl1 = 0x00;
	if (disp_con == PF_DISPLCON_LVDS_DUAL)
		cfg.lvds_interface_ctrl1 |= 0x0b; /* Turn on dual LVDS lane and clock */
	if (color_depth == PF_COLOR_DEPTH_6BIT)
		cfg.lvds_interface_ctrl1 |= 0x20; /* Use 18 bits per pixel */

	cfg.lvds_interface_ctrl2 = 0x03;  /* no clock spreading, 300 mV LVDS swing */
	/* Swap LVDS even and odd lanes for HW-ID 7.9.2.0 only. */
	if (hwilib_get_field(HWID, hwid, sizeof(hwid)) == sizeof(hwid) &&
	    !(memcmp(hwid, tcu31_hwid, sizeof(hwid)))) {
		cfg.lvds_interface_ctrl3 = 0x01;  /* swap LVDS even and odd */
	} else
		cfg.lvds_interface_ctrl3 = 0x00;  /* no LVDS signal swap */
	cfg.t2_delay = 1;		  /* Delay T2 (VDD to LVDS active) by 16 ms */
	cfg.t3_timing = 10;		  /* 500 ms from LVDS to backlight active */
	cfg.t12_timing = 20;		  /* 1 second re-power delay */
	cfg.t4_timing = 3;		  /* 150 ms backlight off to LVDS inactive */
	cfg.t5_delay = 1;		  /* Delay T5 (LVDS to VDD inactive) by 16 ms */
	cfg.backlight_ctrl = 0;		  /* Enable backlight control */

	/* Write back configuration data to PTN3460 */
	status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_CONFIG_OFF,
			   (u8*)&cfg, PTN_CONFIG_LEN);
	if (status)
		return (PTN_BUS_ERROR | status);
	else
		return PTN_NO_ERROR;
}

/** \brief This functions reads one desired EDID data structure from PTN3460
 * @param  edid_num Number of EDID that must be read (0..6)
 * @param  *data    Pointer to a buffer where to store read data
 * @return          0 on success or error code
 */
int ptn3460_read_edid(u8 edid_num, u8 *data)
{
	int status;

	if (edid_num > PTN_MAX_EDID_NUM)
		return PTN_INVALID_EDID;
	/* First enable access to the desired EDID table */
	status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_CONFIG_OFF + 5,
			   &edid_num, 1);
	if (status)
		return (PTN_BUS_ERROR | status);

	/* Now we can simply read back EDID-data */
	status = i2c_read(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_EDID_OFF,
			  data, PTN_EDID_LEN);
	if (status)
		return (PTN_BUS_ERROR | status);
	else
		return PTN_NO_ERROR;
}

/** \brief This functions writes one EDID data structure to PTN3460
 * @param  edid_num  Number of EDID that must be written (0..6)
 * @param  *data     Pointer to a buffer where data to write is stored in
 * @return           0 on success or error code
 */
int ptn3460_write_edid(u8 edid_num, u8 *data)
{
	int status;

	if (edid_num > PTN_MAX_EDID_NUM)
		return PTN_INVALID_EDID;
	/* First enable access to the desired EDID table */
	status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_CONFIG_OFF + 5,
			   &edid_num, 1);
	if (status)
		return (PTN_BUS_ERROR | status);

	/* Now we can simply write EDID-data to ptn3460 */
	status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_EDID_OFF,
			   data, PTN_EDID_LEN);
	if (status)
		return (PTN_BUS_ERROR | status);
	else
		return PTN_NO_ERROR;
}

/** \brief  This functions selects one of 7 EDID-tables inside PTN3460
 *          which should be emulated on display port and turn emulation ON
 * @param   edid_num  Number of EDID to emulate (0..6)
 * @return            0 on success or error code
 */
int ptn_select_edid (u8 edid_num)
{
	int status;
	u8 val;

	if (edid_num > PTN_MAX_EDID_NUM)
		return PTN_INVALID_EDID;
	/* Enable emulation of the desired EDID table */
	val = (edid_num << 1) | 1;
	status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_CONFIG_OFF + 4,
			   &val, 1);
	if (status)
		return (PTN_BUS_ERROR | status);
	else
		return PTN_NO_ERROR;
}

/** \brief This functions performs a flash operation which will write
 *         current configuration table (all the EDID-tables and the
 *         configuration space with a total amount of 1 KByte)
 *         to the internal flash of PTN3460
 * @param  none
 * @return 0 on success or error code
 */
int ptn3460_flash_config(void)
{
	int status;
	struct ptn_3460_flash flash;

	flash.cmd = 0x01;	/* perform erase and flash cycle */
	flash.magic = 0x7845;	/* Magic number to protect flash operation */
	flash.trigger = 0x56;	/* This value starts flash operation */
	status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_FLASH_CFG_OFF,
			   (u8*)&flash, PTN_FLASH_CFG_LEN);
	if (status) {
		return (PTN_BUS_ERROR | status);
	} else {
		/* To ensure the flash operation is finished, we have to wait 300 ms */
		mdelay(300);
		return PTN_NO_ERROR;
	}
}
