/*
 * This file is part of the coreboot 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; 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 <stddef.h>
#include <console/console.h>
#include <string.h>

#include "ehci_debug.h"
#include "usb_ch9.h"
#include "ehci.h"

#define dprintk printk

#define USB_HUB_PORT_CONNECTION		0
#define USB_HUB_PORT_ENABLED		1
#define USB_HUB_PORT_RESET		4
#define USB_HUB_PORT_POWER		8
#define USB_HUB_C_PORT_CONNECTION	16
#define USB_HUB_C_PORT_RESET		20


static int hub_port_status(const char *buf, int feature)
{
	return !!(buf[feature>>3] & (1<<(feature&0x7)));
}

/* After USB port reset, treat device number 0 as an USB hub. Assign it with
 * a device number hub_addr. Then apply enable and reset on downstream port.
 */
static int dbgp_hub_enable(struct ehci_dbg_port *ehci_debug, unsigned char hub_addr,
	unsigned char port)
{
	char status[8];
	int ret, loop;

	/* Assign a devicenumber for the hub. */
	ret = dbgp_control_msg(ehci_debug, 0,
		USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
		USB_REQ_SET_ADDRESS, hub_addr, 0, NULL, 0);
	if (ret < 0)
		goto err;

	/* Enter configured state on hub. */
	ret = dbgp_control_msg(ehci_debug, hub_addr,
		USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
		USB_REQ_SET_CONFIGURATION, 1, 0, NULL, 0);
	if (ret < 0)
		goto err;

	/* Set PORT_POWER, poll for PORT_CONNECTION. */
	ret = dbgp_control_msg(ehci_debug, hub_addr,
		USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER,
		USB_REQ_SET_FEATURE, USB_HUB_PORT_POWER, port, NULL, 0);
	if (ret < 0)
		goto err;

	loop = 100;
	do {
		dbgp_mdelay(10);
		ret = dbgp_control_msg(ehci_debug, hub_addr,
			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_OTHER,
			USB_REQ_GET_STATUS, 0, port, status, 4);
		if (ret < 0)
			goto err;
		if (hub_port_status(status, USB_HUB_PORT_CONNECTION))
			break;
	} while (--loop);
	if (! loop)
		goto err;

	ret = dbgp_control_msg(ehci_debug, hub_addr,
		USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER,
		USB_REQ_CLEAR_FEATURE, USB_HUB_C_PORT_CONNECTION, port, NULL, 0);
	if (ret < 0)
		goto err;


	/* Set PORT_RESET, poll for C_PORT_RESET. */
	ret = dbgp_control_msg(ehci_debug, hub_addr,
		USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER,
		USB_REQ_SET_FEATURE, USB_HUB_PORT_RESET, port, NULL, 0);
	if (ret < 0)
		goto err;

	loop = 100;
	do {
		dbgp_mdelay(10);
		ret = dbgp_control_msg(ehci_debug, hub_addr,
			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_OTHER,
			USB_REQ_GET_STATUS, 0, port, status, 4);
		if (ret < 0)
			goto err;
		if (hub_port_status(status, USB_HUB_C_PORT_RESET))
			break;
	} while (--loop);
	if (! loop)
		goto err;

	ret = dbgp_control_msg(ehci_debug, hub_addr,
		USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER,
		USB_REQ_CLEAR_FEATURE, USB_HUB_C_PORT_RESET, port, NULL, 0);
	if (ret < 0)
		goto err;

	if (hub_port_status(status, USB_HUB_PORT_ENABLED))
		return 0;
err:
	return -1;
}

static void ack_set_configuration(struct dbgp_pipe *pipe, u8 devnum, int timeout)
{
	int i = DBGP_SETUP_EP0;
	while (++i < DBGP_MAX_ENDPOINTS) {
		if (pipe[i].endpoint != 0) {
			pipe[i].devnum = devnum;
			pipe[i].pid = USB_PID_DATA0;
			pipe[i].timeout = timeout;
		}
	}
}

static void activate_endpoints(struct dbgp_pipe *pipe)
{
	int i = DBGP_SETUP_EP0;
	pipe[i].status |= DBGP_EP_ENABLED | DBGP_EP_VALID;
	while (++i < DBGP_MAX_ENDPOINTS) {
		if (pipe[i].endpoint != 0)
			pipe[i].status |= DBGP_EP_ENABLED | DBGP_EP_VALID;
	}
}

static int probe_for_debug_descriptor(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe)
{
	struct usb_debug_descriptor dbgp_desc;
	int configured = 0, ret;
	u8 devnum = 0;

	/* Find the debug device and make it device number 127 */
debug_dev_retry:
	memset(&dbgp_desc, 0, sizeof(dbgp_desc));
	ret = dbgp_control_msg(ehci_debug, devnum,
		USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
		USB_REQ_GET_DESCRIPTOR, (USB_DT_DEBUG << 8), 0,
		&dbgp_desc, sizeof(dbgp_desc));
	if (ret == sizeof(dbgp_desc)) {
		if (dbgp_desc.bLength == sizeof(dbgp_desc) && dbgp_desc.bDescriptorType == USB_DT_DEBUG)
			goto debug_dev_found;
		else
			dprintk(BIOS_INFO, "Invalid debug device descriptor.\n");
	}
	if (devnum == 0) {
		devnum = USB_DEBUG_DEVNUM;
		goto debug_dev_retry;
	} else {
		dprintk(BIOS_INFO, "Could not find attached debug device.\n");
		return -1;
	}
debug_dev_found:

	/* Move the device to 127 if it isn't already there */
	if (devnum != USB_DEBUG_DEVNUM) {
		ret = dbgp_control_msg(ehci_debug, devnum,
			USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
			USB_REQ_SET_ADDRESS, USB_DEBUG_DEVNUM, 0, NULL, 0);
		if (ret < 0) {
			dprintk(BIOS_INFO, "Could not move attached device to %d.\n",
				USB_DEBUG_DEVNUM);
			return -2;
		}
		devnum = USB_DEBUG_DEVNUM;
		dprintk(BIOS_INFO, "EHCI debug device renamed to 127.\n");
	}

	/* Enable the debug interface */
	ret = dbgp_control_msg(ehci_debug, USB_DEBUG_DEVNUM,
		USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
		USB_REQ_SET_FEATURE, USB_DEVICE_DEBUG_MODE, 0, NULL, 0);
	if (ret < 0) {
		dprintk(BIOS_INFO, "Could not enable EHCI debug device.\n");
		return -3;
	}
	dprintk(BIOS_INFO, "EHCI debug interface enabled.\n");

	pipe[DBGP_CONSOLE_EPOUT].endpoint = dbgp_desc.bDebugOutEndpoint;
	pipe[DBGP_CONSOLE_EPIN].endpoint = dbgp_desc.bDebugInEndpoint;

	ack_set_configuration(pipe, devnum, 1000);

	/* Perform a small write. */
	configured = 0;
small_write:
	ret = dbgp_bulk_write_x(&pipe[DBGP_CONSOLE_EPOUT], "USB\r\n",5);
	if (ret < 0) {
		dprintk(BIOS_INFO, "dbgp_bulk_write failed: %d\n", ret);
		if (!configured) {
			/* Send Set Configure request to device. This is required for FX2
			   (CY7C68013) to transfer from USB state Addressed to Configured,
			   only then endpoints other than 0 are enabled. */
			if (dbgp_control_msg(ehci_debug, USB_DEBUG_DEVNUM,
				USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
				USB_REQ_SET_CONFIGURATION, 1, 0, NULL, 0) >= 0) {
				configured = 1;
				goto small_write;
			}
		}
		return -4;
	}
	dprintk(BIOS_INFO, "Test write done\n");
	return 0;
}

/* FTDI FT232H UART programming. */
#define FTDI_SIO_SET_FLOW_CTRL_REQUEST 0x02
#define FTDI_SIO_SET_BAUDRATE_REQUEST  0x03
#define FTDI_SIO_SET_DATA_REQUEST      0x04
#define FTDI_SIO_SET_BITMODE_REQUEST   0x0b

/* Simplified divisor selection for 12MHz base clock only */
static void ft232h_baud(u16 *const value, u16 *const index, u32 baud)
{
	static const u32 fraction_map[8] = { 0, 3, 2, 4, 1, 5, 6, 7 };

	/* divisor must fit into 14 bits */
	if (baud < 733)
		baud = 733;

	/* divisor is given as a fraction of 8 */
	const u32 div8 = ((12 * 1000 * 1000) * 8) / baud;
	/* upper 3 bits fractional part, lower 14 bits integer */
	u32 div = fraction_map[div8 & 7] << 14 | div8 / 8;

	/* special case for 12MHz */
	if (div == 1)
		div = 0;
	/* special case for 8MHz */
	else if (div == (fraction_map[4] << 14 | 1))
		div = 1;

	*value = div;			/* divisor lower 16 bits */
	*index = (div >> 8) & 0x0100;   /* divisor bit 16 */
	*index |= 0x0200;		/* select 120MHz / 10 */
}

static int probe_for_ftdi(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe)
{
	int ret;
	u8 devnum = 0;
	u8 uart_if = 1; /* FTDI_INTERFACE_A 1 */
	u16 baud_value, baud_index;

	/* Move the device to 127 if it isn't already there */
	ret = dbgp_control_msg(ehci_debug, devnum,
		USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
		USB_REQ_SET_ADDRESS, USB_DEBUG_DEVNUM, 0, NULL, 0);
	if (ret < 0) {
		dprintk(BIOS_INFO, "Could not move attached device to %d.\n",
			USB_DEBUG_DEVNUM);
			return -2;
	}
	devnum = USB_DEBUG_DEVNUM;
	dprintk(BIOS_INFO, "EHCI debug device renamed to %d.\n", devnum);

	/* Send Set Configure request to device.  */
	ret = dbgp_control_msg(ehci_debug, devnum,
		USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
		USB_REQ_SET_CONFIGURATION, 1, 0, NULL, 0);
	if (ret < 0) {
		dprintk(BIOS_INFO, "FTDI set configuration failed.\n");
		return -2;
	}

	ret = dbgp_control_msg(ehci_debug, devnum,
		USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
		FTDI_SIO_SET_BITMODE_REQUEST, 0, uart_if, NULL, 0);
	if (ret < 0) {
		dprintk(BIOS_INFO, "FTDI SET_BITMODE failed.\n");
		return -3;
	}
	ft232h_baud(&baud_value, &baud_index,
		    CONFIG_USBDEBUG_DONGLE_FTDI_FT232H_BAUD);
	ret = dbgp_control_msg(ehci_debug, devnum,
		USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
		FTDI_SIO_SET_BAUDRATE_REQUEST,
		baud_value, baud_index | uart_if, NULL, 0);
	if (ret < 0) {
		dprintk(BIOS_INFO, "FTDI SET_BAUDRATE failed.\n");
		return -3;
	}
	ret = dbgp_control_msg(ehci_debug, devnum,
		USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
		FTDI_SIO_SET_DATA_REQUEST,
		0x0008, uart_if, NULL, 0);
	if (ret < 0) {
		dprintk(BIOS_INFO, "FTDI SET_DATA failed.\n");
		return -3;
	}
	ret = dbgp_control_msg(ehci_debug, devnum,
		USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
		FTDI_SIO_SET_FLOW_CTRL_REQUEST,
		0x0000, uart_if, NULL, 0);
	if (ret < 0) {
		dprintk(BIOS_INFO, "FTDI SET_FLOW_CTRL failed.\n");
		return -3;
	}

	pipe[DBGP_CONSOLE_EPOUT].endpoint = 0x02;
	pipe[DBGP_CONSOLE_EPIN].endpoint = 0x81;

	ack_set_configuration(pipe, devnum, 1000);

	/* Perform a small write. */
	ret = dbgp_bulk_write_x(&pipe[DBGP_CONSOLE_EPOUT], "USB\r\n", 5);
	if (ret < 0) {
		dprintk(BIOS_INFO, "dbgp_bulk_write failed: %d\n", ret);
		return -4;
	}
	dprintk(BIOS_INFO, "Test write done\n");
	return 0;
}

int dbgp_probe_gadget(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe)
{
	int ret;

	if (CONFIG_USBDEBUG_OPTIONAL_HUB_PORT != 0) {
		ret = dbgp_hub_enable(ehci_debug, USB_DEBUG_DEVNUM-1,
			CONFIG_USBDEBUG_OPTIONAL_HUB_PORT);
		if (ret < 0) {
			printk(BIOS_INFO, "Could not enable USB hub on debug port.\n");
			return ret;
		}
	}

	if (IS_ENABLED(CONFIG_USBDEBUG_DONGLE_FTDI_FT232H)) {
		ret = probe_for_ftdi(ehci_debug, pipe);
	} else {
		ret = probe_for_debug_descriptor(ehci_debug, pipe);
	}
	if (ret < 0) {
		dprintk(BIOS_INFO, "Could not enable debug dongle.\n");
		return ret;
	}

	activate_endpoints(pipe);
	return 0;
}
