// 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(fxbug.dev/32545): 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");
    return ZX_ERR_TIMED_OUT;
  }
  if (cmd_status & NAND_STATUS_FAIL) {
    zxlogf(ERROR, "%s: nand command returns error", __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);
}
