/* Blackfin Direct Memory Access (DMA) Channel model.

   Copyright (C) 2010-2022 Free Software Foundation, Inc.
   Contributed by Analog Devices, Inc.

   This file is part of simulators.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* This must come before any other includes.  */
#include "defs.h"

#include <stdlib.h>

#include "sim-main.h"
#include "devices.h"
#include "hw-device.h"
#include "dv-bfin_dma.h"
#include "dv-bfin_dmac.h"

/* Note: This DMA implementation requires the producer to be the master when
         the peer is MDMA.  The source is always a slave.  This way we don't
         have the two DMA devices thrashing each other with one trying to
         write and the other trying to read.  */

struct bfin_dma
{
  /* This top portion matches common dv_bfin struct.  */
  bu32 base;
  struct hw *dma_master;
  bool acked;

  struct hw_event *handler;
  unsigned ele_size;
  struct hw *hw_peer;

  /* Order after here is important -- matches hardware MMR layout.  */
  union {
    struct { bu16 ndpl, ndph; };
    bu32 next_desc_ptr;
  };
  union {
    struct { bu16 sal, sah; };
    bu32 start_addr;
  };
  bu16 BFIN_MMR_16 (config);
  bu32 _pad0;
  bu16 BFIN_MMR_16 (x_count);
  bs16 BFIN_MMR_16 (x_modify);
  bu16 BFIN_MMR_16 (y_count);
  bs16 BFIN_MMR_16 (y_modify);
  bu32 curr_desc_ptr, curr_addr;
  bu16 BFIN_MMR_16 (irq_status);
  bu16 BFIN_MMR_16 (peripheral_map);
  bu16 BFIN_MMR_16 (curr_x_count);
  bu32 _pad1;
  bu16 BFIN_MMR_16 (curr_y_count);
  bu32 _pad2;
};
#define mmr_base()      offsetof(struct bfin_dma, next_desc_ptr)
#define mmr_offset(mmr) (offsetof(struct bfin_dma, mmr) - mmr_base())

static const char * const mmr_names[] =
{
  "NEXT_DESC_PTR", "START_ADDR", "CONFIG", "<INV>", "X_COUNT", "X_MODIFY",
  "Y_COUNT", "Y_MODIFY", "CURR_DESC_PTR", "CURR_ADDR", "IRQ_STATUS",
  "PERIPHERAL_MAP", "CURR_X_COUNT", "<INV>", "CURR_Y_COUNT", "<INV>",
};
#define mmr_name(off) mmr_names[(off) / 4]

static bool
bfin_dma_enabled (struct bfin_dma *dma)
{
  return (dma->config & DMAEN);
}

static bool
bfin_dma_running (struct bfin_dma *dma)
{
  return (dma->irq_status & DMA_RUN);
}

static struct hw *
bfin_dma_get_peer (struct hw *me, struct bfin_dma *dma)
{
  if (dma->hw_peer)
    return dma->hw_peer;
  return dma->hw_peer = bfin_dmac_get_peer (me, dma->peripheral_map);
}

static void
bfin_dma_process_desc (struct hw *me, struct bfin_dma *dma)
{
  bu8 ndsize = (dma->config & NDSIZE) >> NDSIZE_SHIFT;
  bu16 _flows[9], *flows = _flows;

  HW_TRACE ((me, "dma starting up %#x", dma->config));

  switch (dma->config & WDSIZE)
    {
    case WDSIZE_32:
      dma->ele_size = 4;
      break;
    case WDSIZE_16:
      dma->ele_size = 2;
      break;
    default:
      dma->ele_size = 1;
      break;
    }

  /* Address has to be mutiple of transfer size.  */
  if (dma->start_addr & (dma->ele_size - 1))
    dma->irq_status |= DMA_ERR;

  if (dma->ele_size != (unsigned) abs (dma->x_modify))
    hw_abort (me, "DMA config (striding) %#x not supported (x_modify: %d)",
	      dma->config, dma->x_modify);

  switch (dma->config & DMAFLOW)
    {
    case DMAFLOW_AUTO:
    case DMAFLOW_STOP:
      if (ndsize)
	hw_abort (me, "DMA config error: DMAFLOW_{AUTO,STOP} requires NDSIZE_0");
      break;
    case DMAFLOW_ARRAY:
      if (ndsize == 0 || ndsize > 7)
	hw_abort (me, "DMA config error: DMAFLOW_ARRAY requires NDSIZE 1...7");
      sim_read (hw_system (me), dma->curr_desc_ptr, (void *)flows, ndsize * 2);
      break;
    case DMAFLOW_SMALL:
      if (ndsize == 0 || ndsize > 8)
	hw_abort (me, "DMA config error: DMAFLOW_SMALL requires NDSIZE 1...8");
      sim_read (hw_system (me), dma->next_desc_ptr, (void *)flows, ndsize * 2);
      break;
    case DMAFLOW_LARGE:
      if (ndsize == 0 || ndsize > 9)
	hw_abort (me, "DMA config error: DMAFLOW_LARGE requires NDSIZE 1...9");
      sim_read (hw_system (me), dma->next_desc_ptr, (void *)flows, ndsize * 2);
      break;
    default:
      hw_abort (me, "DMA config error: invalid DMAFLOW %#x", dma->config);
    }

  if (ndsize)
    {
      bu8 idx;
      bu16 *stores[] = {
	&dma->sal,
	&dma->sah,
	&dma->config,
	&dma->x_count,
	(void *) &dma->x_modify,
	&dma->y_count,
	(void *) &dma->y_modify,
      };

      switch (dma->config & DMAFLOW)
	{
	case DMAFLOW_LARGE:
	  dma->ndph = _flows[1];
	  --ndsize;
	  ++flows;
	case DMAFLOW_SMALL:
	  dma->ndpl = _flows[0];
	  --ndsize;
	  ++flows;
	  break;
	}

      for (idx = 0; idx < ndsize; ++idx)
	*stores[idx] = flows[idx];
    }

  dma->curr_desc_ptr = dma->next_desc_ptr;
  dma->curr_addr = dma->start_addr;
  dma->curr_x_count = dma->x_count ? : 0xffff;
  dma->curr_y_count = dma->y_count ? : 0xffff;
}

static int
bfin_dma_finish_x (struct hw *me, struct bfin_dma *dma)
{
  /* XXX: This would be the time to process the next descriptor.  */
  /* XXX: Should this toggle Enable in dma->config ?  */

  if (dma->config & DI_EN)
    hw_port_event (me, 0, 1);

  if ((dma->config & DMA2D) && dma->curr_y_count > 1)
    {
      dma->curr_y_count -= 1;
      dma->curr_x_count = dma->x_count;

      /* With 2D, last X transfer does not modify curr_addr.  */
      dma->curr_addr = dma->curr_addr - dma->x_modify + dma->y_modify;

      return 1;
    }

  switch (dma->config & DMAFLOW)
    {
    case DMAFLOW_STOP:
      HW_TRACE ((me, "dma is complete"));
      dma->irq_status = (dma->irq_status & ~DMA_RUN) | DMA_DONE;
      return 0;
    default:
      bfin_dma_process_desc (me, dma);
      return 1;
    }
}

static void bfin_dma_hw_event_callback (struct hw *, void *);

static void
bfin_dma_reschedule (struct hw *me, unsigned delay)
{
  struct bfin_dma *dma = hw_data (me);
  if (dma->handler)
    {
      hw_event_queue_deschedule (me, dma->handler);
      dma->handler = NULL;
    }
  if (!delay)
    return;
  HW_TRACE ((me, "scheduling next process in %u", delay));
  dma->handler = hw_event_queue_schedule (me, delay,
					  bfin_dma_hw_event_callback, dma);
}

/* Chew through the DMA over and over.  */
static void
bfin_dma_hw_event_callback (struct hw *me, void *data)
{
  struct bfin_dma *dma = data;
  struct hw *peer;
  struct dv_bfin *bfin_peer;
  bu8 buf[4096];
  unsigned ret, nr_bytes, ele_count;

  dma->handler = NULL;
  peer = bfin_dma_get_peer (me, dma);
  bfin_peer = hw_data (peer);
  ret = 0;
  if (dma->x_modify < 0)
    /* XXX: This sucks performance wise.  */
    nr_bytes = dma->ele_size;
  else
    nr_bytes = min (sizeof (buf), dma->curr_x_count * dma->ele_size);

  /* Pumping a chunk!  */
  bfin_peer->dma_master = me;
  bfin_peer->acked = false;
  if (dma->config & WNR)
    {
      HW_TRACE ((me, "dma transfer to 0x%08lx length %u",
		 (unsigned long) dma->curr_addr, nr_bytes));

      ret = hw_dma_read_buffer (peer, buf, 0, dma->curr_addr, nr_bytes);
      /* Has the DMA stalled ?  abort for now.  */
      if (ret == 0)
	goto reschedule;
      /* XXX: How to handle partial DMA transfers ?  */
      if (ret % dma->ele_size)
	goto error;
      ret = sim_write (hw_system (me), dma->curr_addr, buf, ret);
    }
  else
    {
      HW_TRACE ((me, "dma transfer from 0x%08lx length %u",
		 (unsigned long) dma->curr_addr, nr_bytes));

      ret = sim_read (hw_system (me), dma->curr_addr, buf, nr_bytes);
      if (ret == 0)
	goto reschedule;
      /* XXX: How to handle partial DMA transfers ?  */
      if (ret % dma->ele_size)
	goto error;
      ret = hw_dma_write_buffer (peer, buf, 0, dma->curr_addr, ret, 0);
      if (ret == 0)
	goto reschedule;
    }

  /* Ignore partial writes.  */
  ele_count = ret / dma->ele_size;
  dma->curr_addr += ele_count * dma->x_modify;
  dma->curr_x_count -= ele_count;

  if ((!dma->acked && dma->curr_x_count) || bfin_dma_finish_x (me, dma))
    /* Still got work to do, so schedule again.  */
 reschedule:
    bfin_dma_reschedule (me, ret ? 1 : 5000);

  return;

 error:
  /* Don't reschedule on errors ...  */
  dma->irq_status |= DMA_ERR;
}

static unsigned
bfin_dma_io_write_buffer (struct hw *me, const void *source, int space,
			  address_word addr, unsigned nr_bytes)
{
  struct bfin_dma *dma = hw_data (me);
  bu32 mmr_off;
  bu32 value;
  bu16 *value16p;
  bu32 *value32p;
  void *valuep;

  /* Invalid access mode is higher priority than missing register.  */
  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, true))
    return 0;

  if (nr_bytes == 4)
    value = dv_load_4 (source);
  else
    value = dv_load_2 (source);

  mmr_off = addr % dma->base;
  valuep = (void *)((uintptr_t)dma + mmr_base() + mmr_off);
  value16p = valuep;
  value32p = valuep;

  HW_TRACE_WRITE ();

  /* XXX: All registers are RO when DMA is enabled (except IRQ_STATUS).
          But does the HW discard writes or send up IVGHW ?  The sim
          simply discards atm ... */
  switch (mmr_off)
    {
    case mmr_offset(next_desc_ptr):
    case mmr_offset(start_addr):
    case mmr_offset(curr_desc_ptr):
    case mmr_offset(curr_addr):
      /* Don't require 32bit access as all DMA MMRs can be used as 16bit.  */
      if (!bfin_dma_running (dma))
	{
	  if (nr_bytes == 4)
	    *value32p = value;
	  else
	    *value16p = value;
	}
      else
	HW_TRACE ((me, "discarding write while dma running"));
      break;
    case mmr_offset(x_count):
    case mmr_offset(x_modify):
    case mmr_offset(y_count):
    case mmr_offset(y_modify):
      if (!bfin_dma_running (dma))
	*value16p = value;
      break;
    case mmr_offset(peripheral_map):
      if (!bfin_dma_running (dma))
	{
	  *value16p = (*value16p & CTYPE) | (value & ~CTYPE);
	  /* Clear peripheral peer so it gets looked up again.  */
	  dma->hw_peer = NULL;
	}
      else
	HW_TRACE ((me, "discarding write while dma running"));
      break;
    case mmr_offset(config):
      /* XXX: How to handle updating CONFIG of a running channel ?  */
      if (nr_bytes == 4)
	*value32p = value;
      else
	*value16p = value;

      if (bfin_dma_enabled (dma))
	{
	  dma->irq_status |= DMA_RUN;
	  bfin_dma_process_desc (me, dma);
	  /* The writer is the master.  */
	  if (!(dma->peripheral_map & CTYPE) || (dma->config & WNR))
	    bfin_dma_reschedule (me, 1);
	}
      else
	{
	  dma->irq_status &= ~DMA_RUN;
	  bfin_dma_reschedule (me, 0);
	}
      break;
    case mmr_offset(irq_status):
      dv_w1c_2 (value16p, value, DMA_DONE | DMA_ERR);
      break;
    case mmr_offset(curr_x_count):
    case mmr_offset(curr_y_count):
      if (!bfin_dma_running (dma))
	*value16p = value;
      else
	HW_TRACE ((me, "discarding write while dma running"));
      break;
    default:
      /* XXX: The HW lets the pad regions be read/written ...  */
      dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
      return 0;
    }

  return nr_bytes;
}

static unsigned
bfin_dma_io_read_buffer (struct hw *me, void *dest, int space,
			 address_word addr, unsigned nr_bytes)
{
  struct bfin_dma *dma = hw_data (me);
  bu32 mmr_off;
  bu16 *value16p;
  bu32 *value32p;
  void *valuep;

  /* Invalid access mode is higher priority than missing register.  */
  if (!dv_bfin_mmr_require_16_32 (me, addr, nr_bytes, false))
    return 0;

  mmr_off = addr % dma->base;
  valuep = (void *)((uintptr_t)dma + mmr_base() + mmr_off);
  value16p = valuep;
  value32p = valuep;

  HW_TRACE_READ ();

  /* Hardware lets you read all MMRs as 16 or 32 bits, even reserved.  */
  if (nr_bytes == 4)
    dv_store_4 (dest, *value32p);
  else
    dv_store_2 (dest, *value16p);

  return nr_bytes;
}

static unsigned
bfin_dma_dma_read_buffer (struct hw *me, void *dest, int space,
			  unsigned_word addr, unsigned nr_bytes)
{
  struct bfin_dma *dma = hw_data (me);
  unsigned ret, ele_count;

  HW_TRACE_DMA_READ ();

  /* If someone is trying to read from me, I have to be enabled.  */
  if (!bfin_dma_enabled (dma) && !bfin_dma_running (dma))
    return 0;

  /* XXX: handle x_modify ...  */
  ret = sim_read (hw_system (me), dma->curr_addr, dest, nr_bytes);
  /* Ignore partial writes.  */
  ele_count = ret / dma->ele_size;
  /* Has the DMA stalled ?  abort for now.  */
  if (!ele_count)
    return 0;

  dma->curr_addr += ele_count * dma->x_modify;
  dma->curr_x_count -= ele_count;

  if (dma->curr_x_count == 0)
    bfin_dma_finish_x (me, dma);

  return ret;
}

static unsigned
bfin_dma_dma_write_buffer (struct hw *me, const void *source,
			   int space, unsigned_word addr,
			   unsigned nr_bytes,
			   int violate_read_only_section)
{
  struct bfin_dma *dma = hw_data (me);
  unsigned ret, ele_count;

  HW_TRACE_DMA_WRITE ();

  /* If someone is trying to write to me, I have to be enabled.  */
  if (!bfin_dma_enabled (dma) && !bfin_dma_running (dma))
    return 0;

  /* XXX: handle x_modify ...  */
  ret = sim_write (hw_system (me), dma->curr_addr, source, nr_bytes);
  /* Ignore partial writes.  */
  ele_count = ret / dma->ele_size;
  /* Has the DMA stalled ?  abort for now.  */
  if (!ele_count)
    return 0;

  dma->curr_addr += ele_count * dma->x_modify;
  dma->curr_x_count -= ele_count;

  if (dma->curr_x_count == 0)
    bfin_dma_finish_x (me, dma);

  return ret;
}

static const struct hw_port_descriptor bfin_dma_ports[] =
{
  { "di", 0, 0, output_port, }, /* DMA Interrupt */
  { NULL, 0, 0, 0, },
};

static void
attach_bfin_dma_regs (struct hw *me, struct bfin_dma *dma)
{
  address_word attach_address;
  int attach_space;
  unsigned attach_size;
  reg_property_spec reg;

  if (hw_find_property (me, "reg") == NULL)
    hw_abort (me, "Missing \"reg\" property");

  if (!hw_find_reg_array_property (me, "reg", 0, &reg))
    hw_abort (me, "\"reg\" property must contain three addr/size entries");

  hw_unit_address_to_attach_address (hw_parent (me),
				     &reg.address,
				     &attach_space, &attach_address, me);
  hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);

  if (attach_size != BFIN_MMR_DMA_SIZE)
    hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_DMA_SIZE);

  hw_attach_address (hw_parent (me),
		     0, attach_space, attach_address, attach_size, me);

  dma->base = attach_address;
}

static void
bfin_dma_finish (struct hw *me)
{
  struct bfin_dma *dma;

  dma = HW_ZALLOC (me, struct bfin_dma);

  set_hw_data (me, dma);
  set_hw_io_read_buffer (me, bfin_dma_io_read_buffer);
  set_hw_io_write_buffer (me, bfin_dma_io_write_buffer);
  set_hw_dma_read_buffer (me, bfin_dma_dma_read_buffer);
  set_hw_dma_write_buffer (me, bfin_dma_dma_write_buffer);
  set_hw_ports (me, bfin_dma_ports);

  attach_bfin_dma_regs (me, dma);

  /* Initialize the DMA Channel.  */
  dma->peripheral_map = bfin_dmac_default_pmap (me);
}

const struct hw_descriptor dv_bfin_dma_descriptor[] =
{
  {"bfin_dma", bfin_dma_finish,},
  {NULL, NULL},
};
