/* Blackfin General Purpose Ports (GPIO) 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 "sim-main.h"
#include "devices.h"
#include "dv-bfin_gpio.h"

struct bfin_gpio
{
  bu32 base;

  bu16 int_state;

  /* Order after here is important -- matches hardware MMR layout.  */
  bu16 BFIN_MMR_16(data);
  bu16 BFIN_MMR_16(clear);
  bu16 BFIN_MMR_16(set);
  bu16 BFIN_MMR_16(toggle);
  bu16 BFIN_MMR_16(maska);
  bu16 BFIN_MMR_16(maska_clear);
  bu16 BFIN_MMR_16(maska_set);
  bu16 BFIN_MMR_16(maska_toggle);
  bu16 BFIN_MMR_16(maskb);
  bu16 BFIN_MMR_16(maskb_clear);
  bu16 BFIN_MMR_16(maskb_set);
  bu16 BFIN_MMR_16(maskb_toggle);
  bu16 BFIN_MMR_16(dir);
  bu16 BFIN_MMR_16(polar);
  bu16 BFIN_MMR_16(edge);
  bu16 BFIN_MMR_16(both);
  bu16 BFIN_MMR_16(inen);
};
#define mmr_base()      offsetof(struct bfin_gpio, data)
#define mmr_offset(mmr) (offsetof(struct bfin_gpio, mmr) - mmr_base())

static const char * const mmr_names[] =
{
  "PORTIO", "PORTIO_CLEAR", "PORTIO_SET", "PORTIO_TOGGLE", "PORTIO_MASKA",
  "PORTIO_MASKA_CLEAR", "PORTIO_MASKA_SET", "PORTIO_MASKA_TOGGLE",
  "PORTIO_MASKB", "PORTIO_MASKB_CLEAR", "PORTIO_MASKB_SET",
  "PORTIO_MASKB_TOGGLE", "PORTIO_DIR", "PORTIO_POLAR", "PORTIO_EDGE",
  "PORTIO_BOTH", "PORTIO_INEN",
};
#define mmr_name(off) mmr_names[(off) / 4]

static void
bfin_gpio_forward_int (struct hw *me, struct bfin_gpio *port, bu32 mask,
		       int dst_port)
{
  HW_TRACE ((me, "resending levels on port %c", 'a' + dst_port));
  hw_port_event (me, dst_port, !!(port->int_state & mask));
}
static void
bfin_gpio_forward_ints (struct hw *me, struct bfin_gpio *port)
{
  bfin_gpio_forward_int (me, port, port->maska, 0);
  bfin_gpio_forward_int (me, port, port->maskb, 1);
}

static void
bfin_gpio_forward_ouput (struct hw *me, struct bfin_gpio *port, bu32 odata)
{
  int pin, value, ovalue, bit;

  for (pin = 0; pin < 16; ++pin)
    {
      bit = 1 << pin;

      /* Make sure this is an output pin.  */
      if (!(port->dir & bit))
	continue;

      /* Only signal port if the pin changes value.  */
      value = !!(port->data & bit);
      ovalue = !!(odata & bit);
      if (value == ovalue)
	continue;

      HW_TRACE ((me, "outputting gpio %i changed to %i", pin, value));
      hw_port_event (me, pin, value);
    }
}

static unsigned
bfin_gpio_io_write_buffer (struct hw *me, const void *source, int space,
			   address_word addr, unsigned nr_bytes)
{
  struct bfin_gpio *port = hw_data (me);
  bu32 mmr_off;
  bu16 value;
  bu16 *valuep;
  bu32 data = port->data;

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

  value = dv_load_2 (source);
  mmr_off = addr - port->base;
  valuep = (void *)((unsigned long)port + mmr_base() + mmr_off);

  HW_TRACE_WRITE ();

  switch (mmr_off)
    {
    case mmr_offset(data):
    case mmr_offset(maska):
    case mmr_offset(maskb):
    case mmr_offset(dir):
    case mmr_offset(polar):
    case mmr_offset(edge):
    case mmr_offset(both):
    case mmr_offset(inen):
      *valuep = value;
      break;
    case mmr_offset(clear):
    case mmr_offset(maska_clear):
    case mmr_offset(maskb_clear):
      /* We want to clear the related data MMR.  */
      valuep -= 2;
      dv_w1c_2 (valuep, value, -1);
      break;
    case mmr_offset(set):
    case mmr_offset(maska_set):
    case mmr_offset(maskb_set):
      /* We want to set the related data MMR.  */
      valuep -= 4;
      *valuep |= value;
      break;
    case mmr_offset(toggle):
    case mmr_offset(maska_toggle):
    case mmr_offset(maskb_toggle):
      /* We want to toggle the related data MMR.  */
      valuep -= 6;
      *valuep ^= value;
      break;
    default:
      dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
      return 0;
    }

  /* If updating masks, make sure we send updated port info.  */
  switch (mmr_off)
    {
    case mmr_offset(dir):
    case mmr_offset(data) ... mmr_offset(toggle):
      bfin_gpio_forward_ouput (me, port, data);
      break;
    case mmr_offset(maska) ... mmr_offset(maska_toggle):
      bfin_gpio_forward_int (me, port, port->maska, 0);
      break;
    case mmr_offset(maskb) ... mmr_offset(maskb_toggle):
      bfin_gpio_forward_int (me, port, port->maskb, 1);
      break;
    }

  return nr_bytes;
}

static unsigned
bfin_gpio_io_read_buffer (struct hw *me, void *dest, int space,
			  address_word addr, unsigned nr_bytes)
{
  struct bfin_gpio *port = hw_data (me);
  bu32 mmr_off;
  bu16 *valuep;

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

  mmr_off = addr - port->base;
  valuep = (void *)((unsigned long)port + mmr_base() + mmr_off);

  HW_TRACE_READ ();

  switch (mmr_off)
    {
    case mmr_offset(data):
    case mmr_offset(clear):
    case mmr_offset(set):
    case mmr_offset(toggle):
      dv_store_2 (dest, port->data);
      break;
    case mmr_offset(maska):
    case mmr_offset(maska_clear):
    case mmr_offset(maska_set):
    case mmr_offset(maska_toggle):
      dv_store_2 (dest, port->maska);
      break;
    case mmr_offset(maskb):
    case mmr_offset(maskb_clear):
    case mmr_offset(maskb_set):
    case mmr_offset(maskb_toggle):
      dv_store_2 (dest, port->maskb);
      break;
    case mmr_offset(dir):
    case mmr_offset(polar):
    case mmr_offset(edge):
    case mmr_offset(both):
    case mmr_offset(inen):
      dv_store_2 (dest, *valuep);
      break;
    default:
      dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
      return 0;
    }

  return nr_bytes;
}

static const struct hw_port_descriptor bfin_gpio_ports[] =
{
  { "mask_a", 0, 0, output_port, },
  { "mask_b", 1, 0, output_port, },
  { "p0",     0, 0, bidirect_port, },
  { "p1",     1, 0, bidirect_port, },
  { "p2",     2, 0, bidirect_port, },
  { "p3",     3, 0, bidirect_port, },
  { "p4",     4, 0, bidirect_port, },
  { "p5",     5, 0, bidirect_port, },
  { "p6",     6, 0, bidirect_port, },
  { "p7",     7, 0, bidirect_port, },
  { "p8",     8, 0, bidirect_port, },
  { "p9",     9, 0, bidirect_port, },
  { "p10",   10, 0, bidirect_port, },
  { "p11",   11, 0, bidirect_port, },
  { "p12",   12, 0, bidirect_port, },
  { "p13",   13, 0, bidirect_port, },
  { "p14",   14, 0, bidirect_port, },
  { "p15",   15, 0, bidirect_port, },
  { NULL, 0, 0, 0, },
};

static void
bfin_gpio_port_event (struct hw *me, int my_port, struct hw *source,
		      int source_port, int level)
{
  struct bfin_gpio *port = hw_data (me);
  bool olvl, nlvl;
  bu32 bit = (1 << my_port);

  /* Normalize the level value.  A simulated device can send any value
     it likes to us, but in reality we only care about 0 and 1.  This
     lets us assume only those two values below.  */
  level = !!level;

  HW_TRACE ((me, "pin %i set to %i", my_port, level));

  /* Only screw with state if this pin is set as an input, and the
     input is actually enabled.  */
  if ((port->dir & bit) || !(port->inen & bit))
    {
      HW_TRACE ((me, "ignoring level/int due to DIR=%i INEN=%i",
		 !!(port->dir & bit), !!(port->inen & bit)));
      return;
    }

  /* Get the old pin state for calculating an interrupt.  */
  olvl = !!(port->data & bit);

  /* Update the new pin state.  */
  port->data = (port->data & ~bit) | (level << my_port);

  /* See if this state transition will generate an interrupt.  */
  nlvl = !!(port->data & bit);

  if (port->edge & bit)
    {
      /* Pin is edge triggered.  */
      if (port->both & bit)
	{
	  /* Both edges.  */
	  if (olvl == nlvl)
	    {
	      HW_TRACE ((me, "ignoring int due to EDGE=%i BOTH=%i lvl=%i->%i",
			 !!(port->edge & bit), !!(port->both & bit),
			 olvl, nlvl));
	      return;
	    }
	}
      else
	{
	  /* Just one edge.  */
	  if (!(((port->polar & bit) && olvl > nlvl)
		|| (!(port->polar & bit) && olvl < nlvl)))
	    {
	      HW_TRACE ((me, "ignoring int due to EDGE=%i POLAR=%i lvl=%i->%i",
			 !!(port->edge & bit), !!(port->polar & bit),
			 olvl, nlvl));
	      return;
	    }
	}

      /* Send the signal up, and then fall through to clear it.  */
      port->int_state |= bit;
      bfin_gpio_forward_ints (me, port);
      port->int_state &= ~bit;
    }
  else
    {
      /* Pin is level triggered.  */
      if (nlvl == !!(port->polar & bit))
	{
	  HW_TRACE ((me, "ignoring int due to EDGE=%i POLAR=%i lvl=%i",
		     !!(port->edge & bit), !!(port->polar & bit), nlvl));
	  /* We still need to signal SIC to clear the int, so don't return.  */
	  port->int_state &= ~bit;
	}
      else
	port->int_state |= bit;
    }

  bfin_gpio_forward_ints (me, port);
}

static void
attach_bfin_gpio_regs (struct hw *me, struct bfin_gpio *port)
{
  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_GPIO_SIZE)
    hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_GPIO_SIZE);

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

  port->base = attach_address;
}

static void
bfin_gpio_finish (struct hw *me)
{
  struct bfin_gpio *port;

  port = HW_ZALLOC (me, struct bfin_gpio);

  set_hw_data (me, port);
  set_hw_io_read_buffer (me, bfin_gpio_io_read_buffer);
  set_hw_io_write_buffer (me, bfin_gpio_io_write_buffer);
  set_hw_ports (me, bfin_gpio_ports);
  set_hw_port_event (me, bfin_gpio_port_event);

  attach_bfin_gpio_regs (me, port);
}

const struct hw_descriptor dv_bfin_gpio_descriptor[] =
{
  {"bfin_gpio", bfin_gpio_finish,},
  {NULL, NULL},
};
