// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "sw/device/lib/usbdev.h"


#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
#include "usbdev_regs.h"  // Generated.

#define USBDEV_BASE_ADDR TOP_EARLGREY_USBDEV_BASE_ADDR

#define EXTRACT(n, f) ((n >> USBDEV_##f##_OFFSET) & USBDEV_##f##_MASK)

#define SETBIT(val, bit) (val | 1 << bit)
#define CLRBIT(val, bit) (val & ~(1 << bit))

#define REG32(add) *((volatile uint32_t *)(add))

// Free buffer pool is held on a simple stack
// Initalize to all buffer IDs are free
static void buf_init(usbdev_ctx_t *ctx) {
  for (int i = 0; i < NUM_BUFS; i++) {
    ctx->freebuf[i] = i;
  }
  ctx->nfree = NUM_BUFS;
}

// Allocating a buffer just pops next ID from the stack
usbbufid_t usbdev_buf_allocate_byid(usbdev_ctx_t *ctx) {
  if (ctx->nfree <= 0) {
    return -1;
  }
  return ctx->freebuf[--ctx->nfree];
}

// Freeing a buffer just pushes the ID back on the stack
int usbdev_buf_free_byid(usbdev_ctx_t *ctx, usbbufid_t buf) {
  if ((ctx->nfree >= NUM_BUFS) || (buf >= NUM_BUFS)) {
    return -1;
  }
  ctx->freebuf[ctx->nfree++] = buf;
  return 0;
}

uint32_t *usbdev_buf_idtoaddr(usbdev_ctx_t *ctx, usbbufid_t buf) {
  return (uint32_t *)(USBDEV_BASE_ADDR + USBDEV_BUFFER_REG_OFFSET +
                      (buf * BUF_LENGTH));
}

void usbdev_buf_copyto_byid(usbdev_ctx_t *ctx, usbbufid_t buf, const void *from,
                            size_t len_bytes) {
  int32_t *from_word = (int32_t *)from;
  int len_words;
  volatile uint32_t *bp = usbdev_buf_idtoaddr(ctx, buf);

  if (len_bytes > BUF_LENGTH) {
    len_bytes = BUF_LENGTH;
  }
  // This will round up if len_bytes is not on a multiple of int32_t
  // Always ok to fill the extra bytes since the buffers are aligned
  len_words = (len_bytes + sizeof(int32_t) - 1) / sizeof(int32_t);
  for (int i = 0; i < len_words; i++) {
    bp[i] = from_word[i];
  }
}

// Supply as many buffers to the receive available fifo as possible
inline static void fill_av_fifo(usbdev_ctx_t *ctx) {
  while (!(REG32(USBDEV_BASE_ADDR + USBDEV_USBSTAT_REG_OFFSET) &
           (1 << USBDEV_USBSTAT_AV_FULL))) {
    usbbufid_t buf = usbdev_buf_allocate_byid(ctx);
    if (buf < 0) {
      // no more free buffers, can't fill AV FIFO
      break;
    }
    REG32(USBDEV_BASE_ADDR + USBDEV_AVBUFFER_REG_OFFSET) = buf;
  }
}

void usbdev_sendbuf_byid(usbdev_ctx_t *ctx, usbbufid_t buf, size_t size,
                         int endpoint) {
  uint32_t configin =
      USBDEV_BASE_ADDR + USBDEV_CONFIGIN_0_REG_OFFSET + (4 * endpoint);

  if ((endpoint >= NUM_ENDPOINTS) || (buf >= NUM_BUFS)) {
    return;
  }

  if (size > BUF_LENGTH) {
    size = BUF_LENGTH;
  }

  REG32(configin) = ((buf << USBDEV_CONFIGIN_0_BUFFER_0_OFFSET) |
                     (size << USBDEV_CONFIGIN_0_SIZE_0_OFFSET) |
                     (1 << USBDEV_CONFIGIN_0_RDY_0));
}

void usbdev_poll(usbdev_ctx_t *ctx) {
  uint32_t istate = REG32(USBDEV_BASE_ADDR + USBDEV_INTR_STATE_REG_OFFSET);

  // Do this first to keep things going
  fill_av_fifo(ctx);

  // Process IN completions first so we get the fact that send completed
  // before processing a response
  if (istate & (1 << USBDEV_INTR_STATE_PKT_SENT)) {
    uint32_t sentep = REG32(USBDEV_BASE_ADDR + USBDEV_IN_SENT_REG_OFFSET);
    uint32_t configin = USBDEV_BASE_ADDR + USBDEV_CONFIGIN_0_REG_OFFSET;
    TRC_C('a' + sentep);
    for (int ep = 0; ep < NUM_ENDPOINTS; ep++) {
      if (sentep & (1 << ep)) {
        // Free up the buffer and optionally callback
        int32_t cfgin = REG32(configin + (4 * ep));
        usbdev_buf_free_byid(ctx, EXTRACT(cfgin, CONFIGIN_0_BUFFER_0));
        if (ctx->tx_done_callback[ep]) {
          ctx->tx_done_callback[ep](ctx->ep_ctx[ep]);
        }
      }
    }
    // Write one to clear all the ones we handled
    REG32(USBDEV_BASE_ADDR + USBDEV_IN_SENT_REG_OFFSET) = sentep;
    // Clear the interupt
    REG32(USBDEV_BASE_ADDR + USBDEV_INTR_STATE_REG_OFFSET) =
        (1 << USBDEV_INTR_STATE_PKT_SENT);
  }

  if (istate & (1 << USBDEV_INTR_STATE_PKT_RECEIVED)) {
    while (!(REG32(USBDEV_BASE_ADDR + USBDEV_USBSTAT_REG_OFFSET) &
             (1 << USBDEV_USBSTAT_RX_EMPTY))) {
      uint32_t rxinfo = REG32(USBDEV_BASE_ADDR + USBDEV_RXFIFO_REG_OFFSET);
      usbbufid_t buf = EXTRACT(rxinfo, RXFIFO_BUFFER);
      int size = EXTRACT(rxinfo, RXFIFO_SIZE);
      int endpoint = EXTRACT(rxinfo, RXFIFO_EP);
      int setup = (rxinfo >> USBDEV_RXFIFO_SETUP) & 1;

      if (ctx->rx_callback[endpoint]) {
        ctx->rx_callback[endpoint](ctx->ep_ctx[endpoint], buf, size, setup);
      } else {
        TRC_S("USB: unexpected RX ");
        TRC_I(rxinfo, 24);
      }
      usbdev_buf_free_byid(ctx, buf);
    }
    // Clear the interupt
    REG32(USBDEV_BASE_ADDR + USBDEV_INTR_STATE_REG_OFFSET) =
        (1 << USBDEV_INTR_STATE_PKT_RECEIVED);
  }
  if (istate &
      ~((1 << USBDEV_INTR_STATE_PKT_RECEIVED) |
        (1 << USBDEV_INTR_STATE_PKT_SENT))) {
    TRC_C('I');
    TRC_I(istate, 12);
    TRC_C(' ');
    REG32(USBDEV_BASE_ADDR + USBDEV_INTR_STATE_REG_OFFSET) =
        istate & ~((1 << USBDEV_INTR_STATE_PKT_RECEIVED) |
                   (1 << USBDEV_INTR_STATE_PKT_SENT));
    if (istate & (1 << USBDEV_INTR_ENABLE_LINK_RESET)) {
      // Link reset
      for (int ep = 0; ep < NUM_ENDPOINTS; ep++) {
        if (ctx->reset[ep]) {
          ctx->reset[ep](ctx->ep_ctx[ep]);
        }
      }

      // Clear the interupt
      REG32(USBDEV_BASE_ADDR + USBDEV_INTR_STATE_REG_OFFSET) =
          (1 << USBDEV_INTR_ENABLE_LINK_RESET);
    }
  }
  // TODO - clean this up
  // Frame ticks every 1ms, use to flush data every 16ms
  // (faster in DPI but this seems to work ok)
  // At reset frame count is 0, compare to 1 so no calls before SOF received
  uint32_t usbframe = EXTRACT(
      REG32(USBDEV_BASE_ADDR + USBDEV_USBSTAT_REG_OFFSET), USBSTAT_FRAME);
  if ((usbframe & 0xf) == 1) {
    if (ctx->flushed == 0) {
      for (int i = 0; i < NUM_ENDPOINTS; i++) {
        if (ctx->flush[i]) {
          ctx->flush[i](ctx->ep_ctx[i]);
        }
      }
      ctx->flushed = 1;
    }
  } else {
    ctx->flushed = 0;
  }
  // TODO Errors? What Errors?
}

unsigned int usbdev_get_status(usbdev_ctx_t *ctx) {
  unsigned int status = REG32(USBDEV_BASE_ADDR + USBDEV_USBSTAT_REG_OFFSET);
  return status;
}

unsigned int usbdev_get_link_state(usbdev_ctx_t *ctx) {
  unsigned int link_state = EXTRACT(
      REG32(USBDEV_BASE_ADDR + USBDEV_USBSTAT_REG_OFFSET), USBSTAT_LINK_STATE);
  return link_state;
}

unsigned int usbdev_get_address(usbdev_ctx_t *ctx) {
  unsigned int addr =
      EXTRACT(REG32(USBDEV_BASE_ADDR + USBDEV_USBCTRL_REG_OFFSET),
              USBCTRL_DEVICE_ADDRESS);
  return addr;
}

void usbdev_set_deviceid(usbdev_ctx_t *ctx, int deviceid) {
  REG32(USBDEV_BASE_ADDR + USBDEV_USBCTRL_REG_OFFSET) =
      (1 << USBDEV_USBCTRL_ENABLE) |
      (deviceid << USBDEV_USBCTRL_DEVICE_ADDRESS_OFFSET);
}

void usbdev_halt(usbdev_ctx_t *ctx, int endpoint, int enable) {
  uint32_t epbit = 1 << endpoint;
  uint32_t stall = REG32(USBDEV_BASE_ADDR + USBDEV_STALL_REG_OFFSET);
  if (enable) {
    stall |= epbit;
  } else {
    stall &= ~epbit;
  }
  REG32(USBDEV_BASE_ADDR + USBDEV_STALL_REG_OFFSET) = stall;
  ctx->halted = stall;
  // TODO future addition would be to callback the endpoint driver
  // for now it just sees its traffic has stopped
}

void usbdev_set_iso(usbdev_ctx_t *ctx, int endpoint, int enable) {
  if (enable) {
    REG32(USBDEV_BASE_ADDR + USBDEV_ISO_REG_OFFSET) =
        SETBIT(REG32(USBDEV_BASE_ADDR + USBDEV_ISO_REG_OFFSET), endpoint);
  } else {
    REG32(USBDEV_BASE_ADDR + USBDEV_ISO_REG_OFFSET) =
        CLRBIT(REG32(USBDEV_BASE_ADDR + USBDEV_ISO_REG_OFFSET), endpoint);
  }
}

void usbdev_clear_data_toggle(usbdev_ctx_t *ctx, int endpoint) {
  REG32(USBDEV_BASE_ADDR + USBDEV_DATA_TOGGLE_CLEAR_REG_OFFSET) =
      (1 << endpoint);
}

void usbdev_set_ep0_stall(usbdev_ctx_t *ctx, int stall) {
  if (stall) {
    REG32(USBDEV_BASE_ADDR + USBDEV_STALL_REG_OFFSET) =
        REG32(USBDEV_BASE_ADDR + USBDEV_STALL_REG_OFFSET) | 1;
  } else {
    REG32(USBDEV_BASE_ADDR + USBDEV_STALL_REG_OFFSET) =
        REG32(USBDEV_BASE_ADDR + USBDEV_STALL_REG_OFFSET) & ~(1);
  }
}

// TODO got hang with this inline
int usbdev_can_rem_wake(usbdev_ctx_t *ctx) { return ctx->can_wake; }

void usbdev_endpoint_setup(usbdev_ctx_t *ctx, int ep, int enableout,
                           void *ep_ctx, void (*tx_done)(void *),
                           void (*rx)(void *, usbbufid_t, int, int),
                           void (*flush)(void *), void (*reset)(void *)) {
  ctx->ep_ctx[ep] = ep_ctx;
  ctx->tx_done_callback[ep] = tx_done;
  ctx->rx_callback[ep] = rx;
  ctx->flush[ep] = flush;
  ctx->reset[ep] = reset;
  if (enableout) {
    uint32_t rxen = REG32(USBDEV_BASE_ADDR + USBDEV_RXENABLE_OUT_REG_OFFSET);
    rxen |= (1 << (ep + USBDEV_RXENABLE_OUT_OUT_0));
    REG32(USBDEV_BASE_ADDR + USBDEV_RXENABLE_OUT_REG_OFFSET) = rxen;
  }
}

void usbdev_init(usbdev_ctx_t *ctx, bool pinflip, bool diff_rx, bool diff_tx) {
  // setup context
  for (int i = 0; i < NUM_ENDPOINTS; i++) {
    usbdev_endpoint_setup(ctx, i, 0, NULL, NULL, NULL, NULL, NULL);
  }
  ctx->halted = 0;
  ctx->can_wake = 0;
  buf_init(ctx);

  // All about polling...
  REG32(USBDEV_BASE_ADDR + USBDEV_INTR_ENABLE_REG_OFFSET) = 0;

  // Provide buffers for any reception
  fill_av_fifo(ctx);

  REG32(USBDEV_BASE_ADDR + USBDEV_RXENABLE_SETUP_REG_OFFSET) =
      (1 << USBDEV_RXENABLE_SETUP_SETUP_0);
  REG32(USBDEV_BASE_ADDR + USBDEV_RXENABLE_OUT_REG_OFFSET) =
      (1 << USBDEV_RXENABLE_OUT_OUT_0);

  uint32_t phy_config = (pinflip << USBDEV_PHY_CONFIG_PINFLIP) |
                        (diff_rx << USBDEV_PHY_CONFIG_RX_DIFFERENTIAL_MODE) |
                        (diff_tx << USBDEV_PHY_CONFIG_TX_DIFFERENTIAL_MODE) |
                        (1 << USBDEV_PHY_CONFIG_EOP_SINGLE_BIT);
  REG32(USBDEV_BASE_ADDR + USBDEV_PHY_CONFIG_REG_OFFSET) = phy_config;

  REG32(USBDEV_BASE_ADDR + USBDEV_USBCTRL_REG_OFFSET) =
      (1 << USBDEV_USBCTRL_ENABLE);
}
