// SPDX-License-Identifier: GPL-2.0+
/*
 * Meson GXL and GXM USB2 PHY driver
 *
 * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
 * Copyright (C) 2018 BayLibre, SAS
 * Author: Neil Armstrong <narmstron@baylibre.com>
 */

#include <common.h>
#include <asm/io.h>
#include <bitfield.h>
#include <dm.h>
#include <errno.h>
#include <generic-phy.h>
#include <regmap.h>
#include <power/regulator.h>
#include <clk.h>
#include <asm/arch/usb.h>
#include <asm/arch/cpu_id.h>


#include <linux/compat.h>
#include <linux/ioport.h>

#define RESET_COMPLETE_TIME				500

struct phy_aml_usb2_priv {
	/* controller */
	unsigned int base_addr;
	unsigned int reset_addr;
	/* role */
	int id_mode;
	/* vbus call back */
	unsigned int usb_phy2_base_addr;
	unsigned int u2_port_num;
	unsigned int usb_phy2_pll_base_addr[4];
};

/* return == 1, g12b and revB, tl1 */
static int phy_aml_usb2_check_g12b_revb(void)
{
	cpu_id_t cpu_id = get_cpu_id();

	if (cpu_id.family_id == MESON_CPU_MAJOR_ID_G12B &&
	    cpu_id.chip_rev == 0xb)
		return 1;
	else
		return 0;
}

static void set_usb_pll(struct phy *phy, uint32_t volatile *phy2_pll_base)
{
	unsigned int pll_set1, pll_set2, pll_set3;
	unsigned int tuning_disconnect_threshold = 0x34;

	dev_read_u32(phy->dev, "pll-setting-1", &pll_set1);
	dev_read_u32(phy->dev, "pll-setting-2", &pll_set2);
	dev_read_u32(phy->dev, "pll-setting-3", &pll_set3);
	debug("pll1=0x%08x, pll2=0x%08x, pll-setting-3 =0x%08x\n",
		pll_set1, pll_set2, pll_set3);

	(*(volatile uint32_t *)((unsigned long)phy2_pll_base + 0x40))
		= (pll_set1 | USB_PHY2_RESET | USB_PHY2_ENABLE);
	(*(volatile uint32_t *)((unsigned long)phy2_pll_base + 0x44)) =
		pll_set2;
	(*(volatile uint32_t *)((unsigned long)phy2_pll_base + 0x48)) =
		pll_set3;
	udelay(100);
	(*(volatile uint32_t *)(unsigned long)((unsigned long)phy2_pll_base + 0x40))
		= (((pll_set1) | (USB_PHY2_ENABLE))
			& (~(USB_PHY2_RESET)));

	dev_read_u32(phy->dev, "disconnect-threshold", &tuning_disconnect_threshold);
	(*(volatile uint32_t *)((unsigned long)phy2_pll_base + 0xc)) =
		tuning_disconnect_threshold;
	debug("tuning_disconnect_threshold=0x%x\n", tuning_disconnect_threshold);
}

static int phy_aml_usb2_phy_init(struct phy *phy)
{
	struct u2p_aml_regs *u2p_aml_reg;
	struct phy_aml_usb2_priv *priv = dev_get_priv(phy->dev);
	u2p_r0_t dev_u2p_r0;
	u2p_r1_t dev_u2p_r1;
	int i;
	int cnt;
	unsigned int u2portnum;
	int time_dly = RESET_COMPLETE_TIME;

	priv->reset_addr = dev_read_addr_index(phy->dev, 1);
	if (priv->reset_addr == FDT_ADDR_T_NONE) {
		pr_err("Coun't get usb_phy2_pll_base_addr[%d]\n", i);
		return -1;
	}
	*(volatile unsigned long *)(unsigned long)priv->reset_addr |= (1<<2);

	udelay(time_dly);
	dev_read_u32(phy->dev, "portnum", &u2portnum);
	priv->u2_port_num = u2portnum;

	priv->usb_phy2_pll_base_addr[0] = dev_read_addr_index(phy->dev, 2);
	if (priv->usb_phy2_pll_base_addr[0] == FDT_ADDR_T_NONE) {
		pr_err("Coun't get usb_phy2_pll_base_addr[%d]\n", i);
		return -1;
	}

	priv->usb_phy2_pll_base_addr[1] = dev_read_addr_index(phy->dev, 3);
	if (priv->usb_phy2_pll_base_addr[1] == FDT_ADDR_T_NONE) {
		pr_err("Coun't get usb_phy2_pll_base_addr[%d]\n", i);
		return -1;
	}
	priv->base_addr = dev_read_addr(phy->dev);

	debug("usb2 phy: portnum=%d, addr1= 0x%08x, addr2= 0x%08x\n",
		u2portnum, priv->usb_phy2_pll_base_addr[0],
		priv->usb_phy2_pll_base_addr[1]);

	for (i = 0; i < u2portnum; i++) {
		u2p_aml_reg = (struct u2p_aml_regs *)((ulong)priv->base_addr + i * PHY_REGISTER_SIZE);
		dev_u2p_r0.d32 = u2p_aml_reg->u2p_r0;
		dev_u2p_r0.b.host_device= 1;
		dev_u2p_r0.b.POR= 0;
		u2p_aml_reg->u2p_r0  = dev_u2p_r0.d32;
		udelay(10);
		*(volatile unsigned long *)(unsigned long)priv->reset_addr |= (1 << (16 + i));
		udelay(50);

		/* wait for phy ready */
		dev_u2p_r1.d32  = u2p_aml_reg->u2p_r1;
		cnt = 0;
		while (dev_u2p_r1.b.phy_rdy != 1) {
			dev_u2p_r1.d32 = u2p_aml_reg->u2p_r1;
			/*we wait phy ready max 1ms, common is 100us*/
			if (cnt > 200)
				break;
			else {
				cnt++;
				udelay(5);
			}
		}
	}

	for (i = 0; i < u2portnum; i++) {
		debug("------set usb pll\n");
		set_usb_pll(phy, (volatile uint32_t *)(unsigned long)priv->usb_phy2_pll_base_addr[i]);
	}

	return 0;
}

#if 0

static void phy_aml_usb2_reset(struct phy_aml_usb2_priv *priv)
{
	return;
}

#endif /* 0 */

static int phy_aml_usb2_tuning(struct phy *phy, int port)
{
	struct phy_aml_usb2_priv *priv = dev_get_priv(phy->dev);
	unsigned long phy_reg_base;
	unsigned int pll_set1, pll_set2, pll_set3, pll_set4;

	if (port > 2)
		return 0;

	dev_read_u32(phy->dev, "pll-setting-4", &pll_set1);
	dev_read_u32(phy->dev, "pll-setting-5", &pll_set2);
	dev_read_u32(phy->dev, "pll-setting-7", &pll_set4);
	dev_read_u32(phy->dev, "pll-setting-6", &pll_set3);

	debug("pll1=0x%08x, pll2=0x%08x, pll-setting-3 =0x%08x\n",
			pll_set2, pll_set1, pll_set3);


	phy_reg_base = priv->usb_phy2_pll_base_addr[port];

	if (phy_aml_usb2_check_g12b_revb() == 1) {
		(*(volatile uint32_t *)(phy_reg_base + 0x50)) = pll_set1;
		(*(volatile uint32_t *)(phy_reg_base + 0x54)) = 0x2a;
		(*(volatile uint32_t *)(phy_reg_base + 0x34)) = pll_set3 & (0x1f << 16);
		return 0;
	}

	(*(volatile uint32_t *)(phy_reg_base + 0x10)) = pll_set2;
	(*(volatile uint32_t *)(phy_reg_base + 0x50)) = pll_set1;
	(*(volatile uint32_t *)(phy_reg_base + 0x38)) = pll_set4;
	(*(volatile uint32_t *)(phy_reg_base + 0x34)) = pll_set3;
	return 0;
}

#if 0

static void
phy_aml_usb2_set_host_mode(struct phy_aml_usb2_priv *priv)
{
	return;
}

#endif /* 0 */

static int phy_aml_usb2_power_on(struct phy *phy)
{
	return 0;
}

static int phy_aml_usb2_power_off(struct phy *phy)
{
	return 0;
}

struct phy_ops amlogic_usb2_phy_ops = {
	.init = phy_aml_usb2_phy_init,
	.power_on = phy_aml_usb2_power_on,
	.power_off = phy_aml_usb2_power_off,
	.tuning = phy_aml_usb2_tuning,
};

int phy_aml_usb2_probe(struct udevice *dev)
{
	return 0;
}

static const struct udevice_id phy_aml_usb2_phy_ids[] = {
	{ .compatible = "amlogic, amlogic-new-usb2-v2" },
	{ }
};

U_BOOT_DRIVER(meson_gxl_usb2_phy) = {
	.name = "amlogic_new_usb2_phy",
	.id = UCLASS_PHY,
	.of_match = phy_aml_usb2_phy_ids,
	.probe = phy_aml_usb2_probe,
	.ops = &amlogic_usb2_phy_ops,
	.priv_auto_alloc_size = sizeof(struct phy_aml_usb2_priv),
};
