// 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 "onfi.h"

#include <string.h>
#include <unistd.h>

#include <ddk/debug.h>

// Database of settings for the NAND flash devices we support.
// Note on chip_delay: chip_delay is the delay after we enqueue certain ONFI
// commands (RESET, READSTART). The value of 30us was experimentally picked for
// the Samsung NAND, and 20us for the Toshiba NAND. It turns out that a value
// of 25us works better for the Micron NAND (25us reduces the number of ECC
// errors significantly).
// TODO(ZX-2696): Determine the value of chip delay more scientifically.
static struct nand_chip_table nand_chip_table[] = {
    {0x2C,
     0xDC,
     "Micron",
     "MT29F4G08ABAEA",
     {20, 16, 15},
     {.cmd_flush = {.min = zx::usec(130), .interval = zx::usec(10)},
      .write = {.min = zx::usec(320), .interval = zx::usec(20)},
      .erase = {.min = zx::msec(2), .interval = zx::usec(100)}},
     25,
     true,
     512,
     0,
     0,
     0,
     0},
    {0xEC,
     0xDC,
     "Samsung",
     "K9F4G08U0F",
     {25, 20, 15},
     {.cmd_flush = {.min = zx::usec(130), .interval = zx::usec(10)},
      .write = {.min = zx::usec(320), .interval = zx::usec(20)},
      .erase = {.min = zx::msec(2), .interval = zx::usec(100)}},
     30,
     true,
     512,
     0,
     0,
     0,
     0},
    /* TODO: This works. but doublecheck Toshiba nand_timings from datasheet */
    {0x98,
     0xDC,
     "Toshiba",
     "TC58NVG2S0F",
     {25, 20, /* 15 */ 25},
     {.cmd_flush = {.min = zx::usec(130), .interval = zx::usec(10)},
      .write = {.min = zx::usec(320), .interval = zx::usec(20)},
      .erase = {.min = zx::msec(2), .interval = zx::usec(100)}},
     25,
     true,
     512,
     0,
     0,
     0,
     0},
};

#define NAND_CHIP_TABLE_SIZE (sizeof(nand_chip_table) / sizeof(struct nand_chip_table))

struct nand_chip_table* Onfi::FindNandChipTable(uint8_t manuf_id, uint8_t device_id) {
  for (uint32_t i = 0; i < NAND_CHIP_TABLE_SIZE; i++)
    if (manuf_id == nand_chip_table[i].manufacturer_id && device_id == nand_chip_table[i].device_id)
      return &nand_chip_table[i];
  return NULL;
}

void Onfi::Init(fbl::Function<void(int32_t cmd, uint32_t ctrl)> cmd_ctrl,
                fbl::Function<uint8_t()> read_byte) {
  cmd_ctrl_ = std::move(cmd_ctrl);
  read_byte_ = std::move(read_byte);
}

zx_status_t Onfi::OnfiWait(zx::duration timeout, zx::duration first_interval,
                           zx::duration polling_interval) {
  zx::duration total_time;
  uint8_t cmd_status;

  cmd_ctrl_(NAND_CMD_STATUS, NAND_CTRL_CLE | NAND_CTRL_CHANGE);
  cmd_ctrl_(NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
  bool first = true;
  while (!((cmd_status = read_byte_()) & NAND_STATUS_READY)) {
    zx::duration sleep_interval = first ? first_interval : polling_interval;
    first = false;
    zx::nanosleep(zx::deadline_after(sleep_interval));
    total_time += sleep_interval;
    if (total_time > timeout) {
      break;
    }
  }
  if (!(cmd_status & NAND_STATUS_READY)) {
    zxlogf(ERROR, "nand command wait timed out\n");
    return ZX_ERR_TIMED_OUT;
  }
  if (cmd_status & NAND_STATUS_FAIL) {
    zxlogf(ERROR, "%s: nand command returns error\n", __func__);
    return ZX_ERR_IO;
  }
  return ZX_OK;
}

void Onfi::OnfiCommand(uint32_t command, int32_t column, int32_t page_addr, uint32_t capacity_mb,
                       uint32_t chip_delay_us, int buswidth_16) {
  cmd_ctrl_(command, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
  if (column != -1 || page_addr != -1) {
    uint32_t ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE;

    if (column != -1) {
      /* 16 bit buswidth ? */
      if (buswidth_16)
        column >>= 1;
      cmd_ctrl_(column, ctrl);
      ctrl &= ~NAND_CTRL_CHANGE;
      cmd_ctrl_(column >> 8, ctrl);
    }
    if (page_addr != -1) {
      cmd_ctrl_(page_addr, ctrl);
      cmd_ctrl_(page_addr >> 8, NAND_NCE | NAND_ALE);
      /* one more address cycle for devices > 128M */
      if (capacity_mb > 128)
        cmd_ctrl_(page_addr >> 16, NAND_NCE | NAND_ALE);
    }
  }
  cmd_ctrl_(NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);

  if (command == NAND_CMD_ERASE1 || command == NAND_CMD_ERASE2 || command == NAND_CMD_SEQIN ||
      command == NAND_CMD_PAGEPROG)
    return;
  if (command == NAND_CMD_RESET) {
    usleep(chip_delay_us);
    cmd_ctrl_(NAND_CMD_STATUS, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
    cmd_ctrl_(NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
    /* We have to busy loop until ready */
    while (!(read_byte_() & NAND_STATUS_READY))
      ;
    return;
  }
  if (command == NAND_CMD_READ0) {
    cmd_ctrl_(NAND_CMD_READSTART, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
    cmd_ctrl_(NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
  }
  usleep(chip_delay_us);
}
