// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <limits.h>

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/metadata.h>
#include <ddk/platform-defs.h>
#include <ddk/protocol/ethernet.h>
#include <fbl/algorithm.h>
#include <soc/aml-s912/s912-gpio.h>
#include <soc/aml-s912/s912-hw.h>

#include "vim-gpios.h"
#include "vim.h"

namespace vim {

static const pbus_irq_t eth_mac_irqs[] = {
    {
        .irq = S912_ETH_GMAC_IRQ,
        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
    },
};

static const pbus_mmio_t eth_board_mmios[] = {
    {
        .base = PERIPHS_REG_BASE,
        .length = PERIPHS_REG_SIZE,
    },
    {
        .base = S912_HIU_BASE,
        .length = S912_HIU_LENGTH,
    },
};

static const pbus_mmio_t eth_mac_mmios[] = {
    {
        .base = ETH_MAC_REG_BASE,
        .length = ETH_MAC_REG_SIZE,
    },
};

static const pbus_bti_t eth_mac_btis[] = {
    {
        .iommu_index = 0,
        .bti_id = BTI_ETHERNET,
    },
};

static const pbus_boot_metadata_t eth_mac_metadata[] = {
    {
        .zbi_type = DEVICE_METADATA_MAC_ADDRESS,
        .zbi_extra = 0,
    },
};

static const eth_dev_metadata_t eth_phy_device = {
    .vid = PDEV_VID_REALTEK,
    .pid = PDEV_PID_RTL8211F,
    .did = PDEV_DID_ETH_PHY,
};

static const pbus_metadata_t eth_mac_device_metadata[] = {
    {
        .type = DEVICE_METADATA_ETH_PHY_DEVICE,
        .data_buffer = &eth_phy_device,
        .data_size = sizeof(eth_dev_metadata_t),
    },
};

static const eth_dev_metadata_t eth_mac_device = {
    .vid = PDEV_VID_DESIGNWARE,
    // c++ init error
    .pid = 0,
    // c++ init error
    .did = PDEV_DID_ETH_MAC,
};

static const pbus_metadata_t eth_board_metadata[] = {
    {
        .type = DEVICE_METADATA_ETH_MAC_DEVICE,
        .data_buffer = &eth_mac_device,
        .data_size = sizeof(eth_dev_metadata_t),
    },
};

static pbus_dev_t eth_board_dev = []() {
  pbus_dev_t dev = {};
  dev.name = "ethernet_mac";
  dev.vid = PDEV_VID_AMLOGIC;
  dev.pid = PDEV_PID_AMLOGIC_S912;
  dev.did = PDEV_DID_AMLOGIC_ETH;
  dev.mmio_list = eth_board_mmios;
  dev.mmio_count = countof(eth_board_mmios);
  dev.metadata_list = eth_board_metadata;
  dev.metadata_count = countof(eth_board_metadata);
  return dev;
}();

static pbus_dev_t dwmac_dev = []() {
  pbus_dev_t dev = {};
  dev.name = "dwmac";
  dev.vid = PDEV_VID_DESIGNWARE;
  dev.did = PDEV_DID_ETH_MAC;
  dev.mmio_list = eth_mac_mmios;
  dev.mmio_count = countof(eth_mac_mmios);
  dev.irq_list = eth_mac_irqs;
  dev.irq_count = countof(eth_mac_irqs);
  dev.bti_list = eth_mac_btis;
  dev.bti_count = countof(eth_mac_btis);
  dev.metadata_list = eth_mac_device_metadata;
  dev.metadata_count = countof(eth_mac_device_metadata);
  dev.boot_metadata_list = eth_mac_metadata;
  dev.boot_metadata_count = countof(eth_mac_metadata);
  return dev;
}();

static const zx_bind_inst_t root_match[] = {
    BI_MATCH(),
};

// Composite binding rules for ethernet board driver.
const zx_bind_inst_t i2c_match[] = {
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_I2C),
    BI_ABORT_IF(NE, BIND_I2C_BUS_ID, 1),
    BI_MATCH_IF(EQ, BIND_I2C_ADDRESS, 0x18),
};
static const zx_bind_inst_t gpio_reset_match[] = {
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_GPIO),
    BI_MATCH_IF(EQ, BIND_GPIO_PIN, GPIO_ETH_MAC_RST),
};
static const zx_bind_inst_t gpio_int_match[] = {
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_GPIO),
    BI_MATCH_IF(EQ, BIND_GPIO_PIN, GPIO_ETH_MAC_INTR),
};
static const device_fragment_part_t i2c_fragment[] = {
    {countof(root_match), root_match},
    {countof(i2c_match), i2c_match},
};
static const device_fragment_part_t gpio_reset_fragment[] = {
    {countof(root_match), root_match},
    {countof(gpio_reset_match), gpio_reset_match},
};
static const device_fragment_part_t gpio_int_fragment[] = {
    {countof(root_match), root_match},
    {countof(gpio_int_match), gpio_int_match},
};
static const device_fragment_t eth_fragments[] = {
    {countof(i2c_fragment), i2c_fragment},
    {countof(gpio_int_fragment), gpio_int_fragment},
    {countof(gpio_reset_fragment), gpio_reset_fragment},
};

// Composite binding rules for dwmac.
static const zx_bind_inst_t eth_board_match[] = {
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_ETH_BOARD),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_DESIGNWARE),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_ETH_MAC),
};
static const device_fragment_part_t eth_board_fragment[] = {
    {fbl::count_of(root_match), root_match},
    {fbl::count_of(eth_board_match), eth_board_match},
};
static const device_fragment_t dwmac_fragments[] = {
    {fbl::count_of(eth_board_fragment), eth_board_fragment},
};

zx_status_t Vim::EthInit() {
  // setup pinmux for RGMII connections
  gpio_impl_.SetAltFunction(S912_ETH_MDIO, S912_ETH_MDIO_FN);
  gpio_impl_.SetAltFunction(S912_ETH_MDC, S912_ETH_MDC_FN);
  gpio_impl_.SetAltFunction(S912_ETH_RGMII_RX_CLK, S912_ETH_RGMII_RX_CLK_FN);
  gpio_impl_.SetAltFunction(S912_ETH_RX_DV, S912_ETH_RX_DV_FN);
  gpio_impl_.SetAltFunction(S912_ETH_RXD0, S912_ETH_RXD0_FN);
  gpio_impl_.SetAltFunction(S912_ETH_RXD1, S912_ETH_RXD1_FN);
  gpio_impl_.SetAltFunction(S912_ETH_RXD2, S912_ETH_RXD2_FN);
  gpio_impl_.SetAltFunction(S912_ETH_RXD3, S912_ETH_RXD3_FN);

  gpio_impl_.SetAltFunction(S912_ETH_RGMII_TX_CLK, S912_ETH_RGMII_TX_CLK_FN);
  gpio_impl_.SetAltFunction(S912_ETH_TX_EN, S912_ETH_TX_EN_FN);
  gpio_impl_.SetAltFunction(S912_ETH_TXD0, S912_ETH_TXD0_FN);
  gpio_impl_.SetAltFunction(S912_ETH_TXD1, S912_ETH_TXD1_FN);
  gpio_impl_.SetAltFunction(S912_ETH_TXD2, S912_ETH_TXD2_FN);
  gpio_impl_.SetAltFunction(S912_ETH_TXD3, S912_ETH_TXD3_FN);

  // Add a composite device for ethernet board in a new devhost.
  auto status = pbus_.CompositeDeviceAdd(&eth_board_dev, eth_fragments,
                                         fbl::count_of(eth_fragments), UINT32_MAX);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: CompositeDeviceAdd failed: %d", __func__, status);
    return status;
  }

  // Add a composite device for dwmac driver in the ethernet board driver's devhost.
  status = pbus_.CompositeDeviceAdd(&dwmac_dev, dwmac_fragments, fbl::count_of(dwmac_fragments), 1);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: CompositeDeviceAdd failed: %d", __func__, status);
    return status;
  }

  return ZX_OK;
}
}  // namespace vim
