// Copyright 2019 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 <lib/mmio/mmio.h>

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/metadata.h>
#include <ddk/metadata/spi.h>
#include <ddk/platform-defs.h>
#include <fbl/algorithm.h>
#include <soc/aml-common/aml-spi.h>
#include <soc/aml-s905d2/s905d2-gpio.h>
#include <soc/aml-s905d3/s905d3-hw.h>

#include "nelson-gpios.h"
#include "nelson.h"

#define HHI_SPICC_CLK_CNTL (0xf7 * 4)
#define spicc1_clk_sel_fclk_div2 (4 << 23)
#define spicc1_clk_en (1 << 22)
#define spicc1_clk_div(x) (((x)-1) << 16)

namespace nelson {

static const pbus_mmio_t spi_mmios[] = {
    {
        .base = S905D3_SPICC0_BASE,
        .length = S905D3_SPICC0_LENGTH,
    },
    {
        .base = S905D3_SPICC1_BASE,
        .length = S905D3_SPICC1_LENGTH,
    },
};

static const pbus_irq_t spi_irqs[] = {
    {
        .irq = S905D3_SPICC0_IRQ,
        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
    },
    {
        .irq = S905D3_SPICC1_IRQ,
        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
    },
};

static const spi_channel_t spi_channels[] = {
    // Radar sensor head.
    {
        .bus_id = NELSON_SPICC1,
        .cs = 0,  // index into matching chip-select map
        .vid = PDEV_VID_INFINEON,
        .pid = PDEV_PID_INFINEON_BGT60TR13C,
        .did = PDEV_DID_RADAR_SENSOR,
    }};

static const amlspi_cs_map_t spi_cs_map[] = {
    {.bus_id = NELSON_SPICC0, .cs_count = 0, .cs = {}},  // Unused.
    {
        .bus_id = NELSON_SPICC1, .cs_count = 1, .cs = {0}  // index into fragments list
    },
};

static const pbus_metadata_t spi_metadata[] = {
    {
        .type = DEVICE_METADATA_SPI_CHANNELS,
        .data_buffer = spi_channels,
        .data_size = sizeof spi_channels,
    },
    {
        .type = DEVICE_METADATA_AMLSPI_CS_MAPPING,
        .data_buffer = &spi_cs_map,
        .data_size = sizeof spi_cs_map,
    },
};

static pbus_dev_t spi_dev = []() {
  pbus_dev_t dev = {};
  dev.name = "spi";
  dev.vid = PDEV_VID_AMLOGIC;
  dev.pid = PDEV_PID_GENERIC;
  dev.did = PDEV_DID_AMLOGIC_SPI;
  dev.mmio_list = spi_mmios;
  dev.mmio_count = countof(spi_mmios);
  dev.irq_list = spi_irqs;
  dev.irq_count = countof(spi_irqs);
  dev.metadata_list = spi_metadata;
  dev.metadata_count = countof(spi_metadata);
  return dev;
}();

// composite binding rules
static const zx_bind_inst_t root_match[] = {
    BI_MATCH(),
};
static constexpr zx_bind_inst_t gpio_spicc1_ss0_match[] = {
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_GPIO),
    BI_MATCH_IF(EQ, BIND_GPIO_PIN, GPIO_SPICC1_SS0),
};
static constexpr device_fragment_part_t gpio_spicc1_ss0_fragment[] = {
    {fbl::count_of(root_match), root_match},
    {fbl::count_of(gpio_spicc1_ss0_match), gpio_spicc1_ss0_match},
};
static constexpr device_fragment_t fragments[] = {
    {fbl::count_of(gpio_spicc1_ss0_fragment), gpio_spicc1_ss0_fragment},
};

zx_status_t Nelson::SpiInit() {
  // setup pinmux for SPICC1 bus arbiter.
  gpio_impl_.SetAltFunction(S905D2_GPIOH(4), 3);         // MOSI
  gpio_impl_.SetAltFunction(S905D2_GPIOH(5), 3);         // MISO
  gpio_impl_.ConfigOut(GPIO_SPICC1_SS0, 1);              // SS0
  gpio_impl_.ConfigIn(S905D2_GPIOH(7), GPIO_PULL_DOWN);  // SCLK
  gpio_impl_.SetAltFunction(S905D2_GPIOH(7), 3);         // SCLK

  // TODO(ZX-4230): fix this clock enable block when the clock driver can handle the dividers
  {
    // Please do not use get_root_resource() in new code. See ZX-1467.
    zx::unowned_resource resource(get_root_resource());
    std::optional<ddk::MmioBuffer> buf;
    zx_status_t status = ddk::MmioBuffer::Create(S905D3_HIU_BASE, S905D3_HIU_LENGTH, *resource,
                                                 ZX_CACHE_POLICY_UNCACHED_DEVICE, &buf);
    if (status != ZX_OK) {
      zxlogf(ERROR, "%s: MmioBuffer::Create failed %d", __func__, status);
      return status;
    }

    // SPICC1 clock enable @200MHz (fclk_div2(1GHz) / N(5)).  For final SCLK frequency, see
    // CONREG[16:18] in the SPI controller.  This clock config produces a SCLK frequency of 50MHz
    // assuming a default value for CONREG[16:18].
    buf->Write32(spicc1_clk_sel_fclk_div2 | spicc1_clk_en | spicc1_clk_div(5), HHI_SPICC_CLK_CNTL);
  }

  zx_status_t status =
      pbus_.CompositeDeviceAdd(&spi_dev, fragments, fbl::count_of(fragments), UINT32_MAX);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: DeviceAdd failed %d", __func__, status);
    return status;
  }

  return ZX_OK;
}

}  // namespace nelson
