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

   Copyright (C) 2010-2021 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 *)((unsigned long)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 *)((unsigned long)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},
};
