// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2009
 * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
 * Copyright 2019 Google Inc
 */

#include <common.h>
#include <dm.h>
#include <log.h>
#include <spl.h>
#include <acpi/acpigen.h>
#include <acpi/acpi_device.h>
#include <asm/lpss.h>
#include <dm/acpi.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
#include "designware_i2c.h"

enum {
	VANILLA		= 0,	/* standard I2C with no tweaks */
	INTEL_APL,		/* Apollo Lake I2C */
};

/* BayTrail HCNT/LCNT/SDA hold time */
static struct dw_scl_sda_cfg byt_config = {
	.ss_hcnt = 0x200,
	.fs_hcnt = 0x55,
	.ss_lcnt = 0x200,
	.fs_lcnt = 0x99,
	.sda_hold = 0x6,
};

/* Have a weak function for now - possibly should be a new uclass */
__weak void lpss_reset_release(void *regs);

static int designware_i2c_pci_ofdata_to_platdata(struct udevice *dev)
{
	struct dw_i2c *priv = dev_get_priv(dev);

	if (spl_phase() < PHASE_SPL) {
		u32 base;
		int ret;

		ret = dev_read_u32(dev, "early-regs", &base);
		if (ret)
			return log_msg_ret("early-regs", ret);

		/* Set i2c base address */
		dm_pci_write_config32(dev, PCI_BASE_ADDRESS_0, base);

		/* Enable memory access and bus master */
		dm_pci_write_config32(dev, PCI_COMMAND, PCI_COMMAND_MEMORY |
				      PCI_COMMAND_MASTER);
	}

	if (spl_phase() < PHASE_BOARD_F) {
		/* Handle early, fixed mapping into a different address space */
		priv->regs = (struct i2c_regs *)dm_pci_read_bar32(dev, 0);
	} else {
		priv->regs = (struct i2c_regs *)
			dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
	}
	if (!priv->regs)
		return -EINVAL;

	/* Save base address from PCI BAR */
	if (IS_ENABLED(CONFIG_INTEL_BAYTRAIL))
		/* Use BayTrail specific timing values */
		priv->scl_sda_cfg = &byt_config;
	if (dev_get_driver_data(dev) == INTEL_APL)
		priv->has_spk_cnt = true;

	return designware_i2c_ofdata_to_platdata(dev);
}

static int designware_i2c_pci_probe(struct udevice *dev)
{
	struct dw_i2c *priv = dev_get_priv(dev);

	if (dev_get_driver_data(dev) == INTEL_APL) {
		/* Ensure controller is in D0 state */
		lpss_set_power_state(dev, STATE_D0);

		lpss_reset_release(priv->regs);
	}

	return designware_i2c_probe(dev);
}

static int designware_i2c_pci_bind(struct udevice *dev)
{
	char name[20];

	if (dev_of_valid(dev))
		return 0;

	/*
	 * Create a unique device name for PCI type devices
	 * ToDo:
	 * Setting req_seq in the driver is probably not recommended.
	 * But without a DT alias the number is not configured. And
	 * using this driver is impossible for PCIe I2C devices.
	 * This can be removed, once a better (correct) way for this
	 * is found and implemented.
	 *
	 * TODO(sjg@chromium.org): Perhaps if uclasses had platdata this would
	 * be possible. We cannot use static data in drivers since they may be
	 * used in SPL or before relocation.
	 */
	dev->req_seq = uclass_find_next_free_req_seq(UCLASS_I2C);
	sprintf(name, "i2c_designware#%u", dev->req_seq);
	device_set_name(dev, name);

	return 0;
}

/*
 * Write ACPI object to describe speed configuration.
 *
 * ACPI Object: Name ("xxxx", Package () { scl_lcnt, scl_hcnt, sda_hold }
 *
 * SSCN: I2C_SPEED_STANDARD
 * FMCN: I2C_SPEED_FAST
 * FPCN: I2C_SPEED_FAST_PLUS
 * HSCN: I2C_SPEED_HIGH
 */
static void dw_i2c_acpi_write_speed_config(struct acpi_ctx *ctx,
					   struct dw_i2c_speed_config *config)
{
	switch (config->speed_mode) {
	case IC_SPEED_MODE_HIGH:
		acpigen_write_name(ctx, "HSCN");
		break;
	case IC_SPEED_MODE_FAST_PLUS:
		acpigen_write_name(ctx, "FPCN");
		break;
	case IC_SPEED_MODE_FAST:
		acpigen_write_name(ctx, "FMCN");
		break;
	case IC_SPEED_MODE_STANDARD:
	default:
		acpigen_write_name(ctx, "SSCN");
	}

	/* Package () { scl_lcnt, scl_hcnt, sda_hold } */
	acpigen_write_package(ctx, 3);
	acpigen_write_word(ctx, config->scl_hcnt);
	acpigen_write_word(ctx, config->scl_lcnt);
	acpigen_write_dword(ctx, config->sda_hold);
	acpigen_pop_len(ctx);
}

/*
 * Generate I2C timing information into the SSDT for the OS driver to consume,
 * optionally applying override values provided by the caller.
 */
static int dw_i2c_acpi_fill_ssdt(const struct udevice *dev,
				 struct acpi_ctx *ctx)
{
	struct dw_i2c_speed_config config;
	char path[ACPI_PATH_MAX];
	u32 speeds[4];
	uint speed;
	int size;
	int ret;

	/* If no device-tree node, ignore this since we assume it isn't used */
	if (!dev_of_valid(dev))
		return 0;

	ret = acpi_device_path(dev, path, sizeof(path));
	if (ret)
		return log_msg_ret("path", ret);

	size = dev_read_size(dev, "i2c,speeds");
	if (size < 0)
		return log_msg_ret("i2c,speeds", -EINVAL);

	size /= sizeof(u32);
	if (size > ARRAY_SIZE(speeds))
		return log_msg_ret("array", -E2BIG);

	ret = dev_read_u32_array(dev, "i2c,speeds", speeds, size);
	if (ret)
		return log_msg_ret("read", -E2BIG);

	speed = dev_read_u32_default(dev, "clock-frequency", 100000);
	acpigen_write_scope(ctx, path);
	ret = dw_i2c_gen_speed_config(dev, speed, &config);
	if (ret)
		return log_msg_ret("config", ret);
	dw_i2c_acpi_write_speed_config(ctx, &config);
	acpigen_pop_len(ctx);

	return 0;
}

struct acpi_ops dw_i2c_acpi_ops = {
	.fill_ssdt	= dw_i2c_acpi_fill_ssdt,
};

static const struct udevice_id designware_i2c_pci_ids[] = {
	{ .compatible = "snps,designware-i2c-pci" },
	{ .compatible = "intel,apl-i2c", .data = INTEL_APL },
	{ }
};

U_BOOT_DRIVER(i2c_designware_pci) = {
	.name	= "i2c_designware_pci",
	.id	= UCLASS_I2C,
	.of_match = designware_i2c_pci_ids,
	.bind	= designware_i2c_pci_bind,
	.ofdata_to_platdata	= designware_i2c_pci_ofdata_to_platdata,
	.probe	= designware_i2c_pci_probe,
	.priv_auto_alloc_size = sizeof(struct dw_i2c),
	.remove = designware_i2c_remove,
	.flags = DM_FLAG_OS_PREPARE,
	.ops	= &designware_i2c_ops,
	ACPI_OPS_PTR(&dw_i2c_acpi_ops)
};

static struct pci_device_id designware_pci_supported[] = {
	/* Intel BayTrail has 7 I2C controller located on the PCI bus */
	{ PCI_VDEVICE(INTEL, 0x0f41) },
	{ PCI_VDEVICE(INTEL, 0x0f42) },
	{ PCI_VDEVICE(INTEL, 0x0f43) },
	{ PCI_VDEVICE(INTEL, 0x0f44) },
	{ PCI_VDEVICE(INTEL, 0x0f45) },
	{ PCI_VDEVICE(INTEL, 0x0f46) },
	{ PCI_VDEVICE(INTEL, 0x0f47) },
	{ PCI_VDEVICE(INTEL, 0x5aac), .driver_data = INTEL_APL },
	{ PCI_VDEVICE(INTEL, 0x5aae), .driver_data = INTEL_APL },
	{ PCI_VDEVICE(INTEL, 0x5ab0), .driver_data = INTEL_APL },
	{ PCI_VDEVICE(INTEL, 0x5ab2), .driver_data = INTEL_APL },
	{ PCI_VDEVICE(INTEL, 0x5ab4), .driver_data = INTEL_APL },
	{ PCI_VDEVICE(INTEL, 0x5ab6), .driver_data = INTEL_APL },
	{},
};

U_BOOT_PCI_DEVICE(i2c_designware_pci, designware_pci_supported);
