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

#include "common.h"
#include "flash_ctrl_regs.h"

#define FLASH_CTRL0_BASE_ADDR 0x40030000

typedef enum flash_op {
  FlashRead = 0,
  FlashProg = 1,
  FlashErase = 2
} flash_op_t;

typedef enum erase_type { PageErase = 0, BankErase = 1 } erase_type_t;

/* Wait for flash command to complete and set ACK in controller */
static inline void wait_done_and_ack(void) {
  while ((REG32(FLASH_CTRL_OP_STATUS(0)) & (1 << FLASH_CTRL_OP_STATUS_DONE)) ==
         0) {
  };
  REG32(FLASH_CTRL_OP_STATUS(0)) = 0;
}

void flash_init_block(void) {
  while ((REG32(FLASH_CTRL_STATUS(0)) & (1 << FLASH_CTRL_STATUS_INIT_WIP)) >
         0) {
  }
}

int flash_check_empty(void) {
  uint32_t mask = -1u;
  uint32_t *p = (uint32_t *)FLASH_MEM_BASE_ADDR;
  // TODO: Update range to cover entire flash. Limited now to one bank while
  // we debu initialization.
  for (; p < (uint32_t *)(FLASH_MEM_BASE_ADDR + FLASH_BANK_SZ);) {
    mask &= *p++;
    mask &= *p++;
    mask &= *p++;
    mask &= *p++;
    mask &= *p++;
    mask &= *p++;
    mask &= *p++;
    mask &= *p++;
    if (mask != -1u) {
      return 0;
    }
  }
  return 1;
}

int flash_bank_erase(bank_index_t idx) {
  REG32(FLASH_CTRL_MP_BANK_CFG(0)) =
      0x1 << ((idx == FlashBank0) ? FLASH_CTRL_MP_BANK_CFG_ERASE_EN0
                                  : FLASH_CTRL_MP_BANK_CFG_ERASE_EN1);

  // TODO: Add timeout conditions and add error codes.
  REG32(FLASH_CTRL_ADDR(0)) = (idx == FlashBank0)
                                  ? FLASH_MEM_BASE_ADDR
                                  : (FLASH_MEM_BASE_ADDR + FLASH_BANK_SZ);
  REG32(FLASH_CTRL_CONTROL(0)) = (FlashErase << FLASH_CTRL_CONTROL_OP_OFFSET |
                                  BankErase << FLASH_CTRL_CONTROL_ERASE_SEL |
                                  0x1 << FLASH_CTRL_CONTROL_START);
  wait_done_and_ack();

  REG32(FLASH_CTRL_MP_BANK_CFG(0)) =
      0x0 << ((idx == FlashBank0) ? FLASH_CTRL_MP_BANK_CFG_ERASE_EN0
                                  : FLASH_CTRL_MP_BANK_CFG_ERASE_EN1);
  return 0;
}

static int flash_write_internal(uint32_t addr, const uint32_t *data,
                                uint32_t size) {
  // TODO: Do we need to select bank as part of the write?
  // TODO: Update with address alignment requirements.
  REG32(FLASH_CTRL_ADDR(0)) = addr;
  REG32(FLASH_CTRL_CONTROL(0)) = (FlashProg << FLASH_CTRL_CONTROL_OP_OFFSET |
                                  (size - 1) << FLASH_CTRL_CONTROL_NUM_OFFSET |
                                  0x1 << FLASH_CTRL_CONTROL_START);
  for (int i = 0; i < size; ++i) {
    REG32(FLASH_CTRL_PROG_FIFO(FLASH_CTRL0_BASE_ADDR)) = data[i];
  }
  wait_done_and_ack();
  return 0;
}

int flash_write(uint32_t addr, const uint32_t *data, uint32_t size) {
  // TODO: Breakdown into FIFO chunks if needed.
  return flash_write_internal(addr, data, size);
}

void flash_default_region_access(bool rd_en, bool prog_en, bool erase_en) {
  REG32(FLASH_CTRL_DEFAULT_REGION(0)) =
      rd_en << FLASH_CTRL_DEFAULT_REGION_RD_EN |
      prog_en << FLASH_CTRL_DEFAULT_REGION_PROG_EN |
      erase_en << FLASH_CTRL_DEFAULT_REGION_ERASE_EN;
}
