// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
 * (C) Copyright 2018 Neil Armstrong <narmstrong@baylibre.com>
 */

#include <common.h>
#include <asm/arch/boot.h>
#include <asm/arch/eth.h>
#include <asm/arch/g12a.h>
#include <asm/arch/mem.h>
#include <asm/arch/meson-vpu.h>
#include <asm/io.h>
#include <asm/armv8/mmu.h>
#include <linux/sizes.h>
#include <usb.h>
#include <linux/usb/otg.h>
#include <asm/arch/usb.h>
#include <usb/dwc2_udc.h>
#include <phy.h>
#include <clk.h>

DECLARE_GLOBAL_DATA_PTR;

int meson_get_boot_device(void)
{
	return readl(G12A_AO_SEC_GP_CFG0) & G12A_AO_BOOT_DEVICE;
}

/* Configure the reserved memory zones exported by the secure registers
 * into EFI and DTB reserved memory entries.
 */
void meson_init_reserved_memory(void *fdt)
{
	u64 bl31_size, bl31_start;
	u64 bl32_size, bl32_start;
	u32 reg;

	/*
	 * Get ARM Trusted Firmware reserved memory zones in :
	 * - AO_SEC_GP_CFG3: bl32 & bl31 size in KiB, can be 0
	 * - AO_SEC_GP_CFG5: bl31 physical start address, can be NULL
	 * - AO_SEC_GP_CFG4: bl32 physical start address, can be NULL
	 */
	reg = readl(G12A_AO_SEC_GP_CFG3);

	bl31_size = ((reg & G12A_AO_BL31_RSVMEM_SIZE_MASK)
			>> G12A_AO_BL31_RSVMEM_SIZE_SHIFT) * SZ_1K;
	bl32_size = (reg & G12A_AO_BL32_RSVMEM_SIZE_MASK) * SZ_1K;

	bl31_start = readl(G12A_AO_SEC_GP_CFG5);
	bl32_start = readl(G12A_AO_SEC_GP_CFG4);

	/* Add BL31 reserved zone */
	if (bl31_start && bl31_size)
		meson_board_add_reserved_memory(fdt, bl31_start, bl31_size);

	/* Add BL32 reserved zone */
	if (bl32_start && bl32_size)
		meson_board_add_reserved_memory(fdt, bl32_start, bl32_size);

#if defined(CONFIG_VIDEO_MESON)
	meson_vpu_rsv_fb(fdt);
#endif
}

phys_size_t get_effective_memsize(void)
{
	/* Size is reported in MiB, convert it in bytes */
	return min(((readl(G12A_AO_SEC_GP_CFG0) & G12A_AO_MEM_SIZE_MASK)
			>> G12A_AO_MEM_SIZE_SHIFT) * SZ_1M, 0xf5000000);
}

static struct mm_region g12a_mem_map[] = {
	{
		.virt = 0x0UL,
		.phys = 0x0UL,
		.size = 0xf5000000UL,
		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
			 PTE_BLOCK_INNER_SHARE
	}, {
		.virt = 0xf5000000UL,
		.phys = 0xf5000000UL,
		.size = 0x0b000000UL,
		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
			 PTE_BLOCK_NON_SHARE |
			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
	}, {
		/* List terminator */
		0,
	}
};

struct mm_region *mem_map = g12a_mem_map;

static void g12a_enable_external_mdio(void)
{
	writel(0x0, ETH_PHY_CNTL2);
}

static void g12a_enable_internal_mdio(void)
{
	/* Fire up the PHY PLL */
	writel(0x29c0040a, ETH_PLL_CNTL0);
	writel(0x927e0000, ETH_PLL_CNTL1);
	writel(0xac5f49e5, ETH_PLL_CNTL2);
	writel(0x00000000, ETH_PLL_CNTL3);
	writel(0x00000000, ETH_PLL_CNTL4);
	writel(0x20200000, ETH_PLL_CNTL5);
	writel(0x0000c002, ETH_PLL_CNTL6);
	writel(0x00000023, ETH_PLL_CNTL7);
	writel(0x39c0040a, ETH_PLL_CNTL0);
	writel(0x19c0040a, ETH_PLL_CNTL0);

	/* Select the internal MDIO */
	writel(0x33000180, ETH_PHY_CNTL0);
	writel(0x00074043, ETH_PHY_CNTL1);
	writel(0x00000260, ETH_PHY_CNTL2);
}

/* Configure the Ethernet MAC with the requested interface mode
 * with some optional flags.
 */
void meson_eth_init(phy_interface_t mode, unsigned int flags)
{
	switch (mode) {
	case PHY_INTERFACE_MODE_RGMII:
	case PHY_INTERFACE_MODE_RGMII_ID:
	case PHY_INTERFACE_MODE_RGMII_RXID:
	case PHY_INTERFACE_MODE_RGMII_TXID:
		/* Set RGMII mode */
		setbits_le32(G12A_ETH_REG_0, G12A_ETH_REG_0_PHY_INTF_RGMII |
			     G12A_ETH_REG_0_TX_PHASE(1) |
			     G12A_ETH_REG_0_TX_RATIO(4) |
			     G12A_ETH_REG_0_PHY_CLK_EN |
			     G12A_ETH_REG_0_CLK_EN);
		g12a_enable_external_mdio();
		break;

	case PHY_INTERFACE_MODE_RMII:
		/* Set RMII mode */
		out_le32(G12A_ETH_REG_0, G12A_ETH_REG_0_PHY_INTF_RMII |
					G12A_ETH_REG_0_INVERT_RMII_CLK |
					G12A_ETH_REG_0_CLK_EN);

		/* Use G12A RMII Internal PHY */
		if (flags & MESON_USE_INTERNAL_RMII_PHY)
			g12a_enable_internal_mdio();
		else
			g12a_enable_external_mdio();

		break;

	default:
		printf("Invalid Ethernet interface mode\n");
		return;
	}

	/* Enable power gate */
	clrbits_le32(G12A_MEM_PD_REG_0, G12A_MEM_PD_REG_0_ETH_MASK);
}

#if CONFIG_IS_ENABLED(USB_DWC3_MESON_G12A) && \
	CONFIG_IS_ENABLED(USB_GADGET_DWC2_OTG)
static struct dwc2_plat_otg_data meson_g12a_dwc2_data;

int board_usb_init(int index, enum usb_init_type init)
{
	struct fdtdec_phandle_args args;
	const void *blob = gd->fdt_blob;
	int node, dwc2_node;
	struct udevice *dev, *clk_dev;
	struct clk clk;
	int ret;

	/* find the usb glue node */
	node = fdt_node_offset_by_compatible(blob, -1,
					     "amlogic,meson-g12a-usb-ctrl");
	if (node < 0) {
		debug("Not found usb-control node\n");
		return -ENODEV;
	}

	if (!fdtdec_get_is_enabled(blob, node)) {
		debug("usb is disabled in the device tree\n");
		return -ENODEV;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_SIMPLE_BUS, node, &dev);
	if (ret) {
		debug("Not found usb-control device\n");
		return ret;
	}

	/* find the dwc2 node */
	dwc2_node = fdt_node_offset_by_compatible(blob, node,
						  "amlogic,meson-g12a-usb");
	if (dwc2_node < 0) {
		debug("Not found dwc2 node\n");
		return -ENODEV;
	}

	if (!fdtdec_get_is_enabled(blob, dwc2_node)) {
		debug("dwc2 is disabled in the device tree\n");
		return -ENODEV;
	}

	meson_g12a_dwc2_data.regs_otg = fdtdec_get_addr(blob, dwc2_node, "reg");
	if (meson_g12a_dwc2_data.regs_otg == FDT_ADDR_T_NONE) {
		debug("usbotg: can't get base address\n");
		return -ENODATA;
	}

	/* Enable clock */
	ret = fdtdec_parse_phandle_with_args(blob, dwc2_node, "clocks",
					     "#clock-cells", 0, 0, &args);
	if (ret) {
		debug("usbotg has no clocks defined in the device tree\n");
		return ret;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &clk_dev);
	if (ret)
		return ret;

	if (args.args_count != 1) {
		debug("Can't find clock ID in the device tree\n");
		return -ENODATA;
	}

	clk.dev = clk_dev;
	clk.id = args.args[0];

	ret = clk_enable(&clk);
	if (ret) {
		debug("Failed to enable usbotg clock\n");
		return ret;
	}

	meson_g12a_dwc2_data.rx_fifo_sz = fdtdec_get_int(blob, dwc2_node,
						     "g-rx-fifo-size", 0);
	meson_g12a_dwc2_data.np_tx_fifo_sz = fdtdec_get_int(blob, dwc2_node,
							"g-np-tx-fifo-size", 0);
	meson_g12a_dwc2_data.tx_fifo_sz = fdtdec_get_int(blob, dwc2_node,
						     "g-tx-fifo-size", 0);

	/* Switch to peripheral mode */
	ret = dwc3_meson_g12a_force_mode(dev, USB_DR_MODE_PERIPHERAL);
	if (ret)
		return ret;

	return dwc2_udc_probe(&meson_g12a_dwc2_data);
}

int board_usb_cleanup(int index, enum usb_init_type init)
{
	const void *blob = gd->fdt_blob;
	struct udevice *dev;
	int node;
	int ret;

	/* find the usb glue node */
	node = fdt_node_offset_by_compatible(blob, -1,
					     "amlogic,meson-g12a-usb-ctrl");
	if (node < 0)
		return -ENODEV;

	if (!fdtdec_get_is_enabled(blob, node))
		return -ENODEV;

	ret = uclass_get_device_by_of_offset(UCLASS_SIMPLE_BUS, node, &dev);
	if (ret)
		return ret;

	/* Switch to OTG mode */
	ret = dwc3_meson_g12a_force_mode(dev, USB_DR_MODE_HOST);
	if (ret)
		return ret;

	return 0;
}
#endif
