/* Blackfin General Purpose Ports (GPIO) model
   For "new style" GPIOs on BF54x parts.

   Copyright (C) 2010-2013 Free Software Foundation, Inc.
   Contributed by Analog Devices, Inc. and Mike Frysinger.

   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/>.  */

#include "config.h"

#include "sim-main.h"
#include "devices.h"
#include "dv-bfin_gpio2.h"

struct bfin_gpio
{
  bu32 base;

  /* Only accessed indirectly via dir_{set,clear}.  */
  bu16 dir;

  /* Make sure hardware MMRs are aligned.  */
  bu16 _pad;

  /* Order after here is important -- matches hardware MMR layout.  */
  bu16 BFIN_MMR_16(fer);
  bu16 BFIN_MMR_16(data);
  bu16 BFIN_MMR_16(set);
  bu16 BFIN_MMR_16(clear);
  bu16 BFIN_MMR_16(dir_set);
  bu16 BFIN_MMR_16(dir_clear);
  bu16 BFIN_MMR_16(inen);
  bu32 mux;
};
#define mmr_base()      offsetof(struct bfin_gpio, fer)
#define mmr_offset(mmr) (offsetof(struct bfin_gpio, mmr) - mmr_base())

static const char * const mmr_names[] =
{
  "PORTIO_FER", "PORTIO", "PORTIO_SET", "PORTIO_CLEAR", "PORTIO_DIR_SET",
  "PORTIO_DIR_CLEAR", "PORTIO_INEN", "PORTIO_MUX",
};
#define mmr_name(off) mmr_names[(off) / 4]

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;
  bu32 value;
  bu16 *value16p;
  bu32 *value32p;
  void *valuep;

  if (nr_bytes == 4)
    value = dv_load_4 (source);
  else
    value = dv_load_2 (source);
  mmr_off = addr - port->base;
  valuep = (void *)((unsigned long)port + mmr_base() + mmr_off);
  value16p = valuep;
  value32p = valuep;

  HW_TRACE_WRITE ();

  if (mmr_off == mmr_offset (mux))
    dv_bfin_mmr_require_32 (me, addr, nr_bytes, true);
  else
    dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);

  switch (mmr_off)
    {
    case mmr_offset(fer):
    case mmr_offset(data):
    case mmr_offset(inen):
      *value16p = value;
      break;
    case mmr_offset(clear):
      /* We want to clear the related data MMR.  */
      dv_w1c_2 (&port->data, value, -1);
      break;
    case mmr_offset(set):
      /* We want to set the related data MMR.  */
      port->data |= value;
      break;
    case mmr_offset(dir_clear):
      dv_w1c_2 (&port->dir, value, -1);
      break;
    case mmr_offset(dir_set):
      port->dir |= value;
      break;
    case mmr_offset(mux):
      *value32p = value;
      break;
    default:
      dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
      break;
    }

  /* If tweaking output pins, make sure we send updated port info.  */
  switch (mmr_off)
    {
    case mmr_offset(data):
    case mmr_offset(set):
    case mmr_offset(clear):
    case mmr_offset(dir_set):
      {
	int i;
	bu32 bit;

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

	    if (!(port->inen & bit))
	      hw_port_event (me, i, !!(port->data & bit));
	  }

	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 *value16p;
  bu32 *value32p;
  void *valuep;

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

  HW_TRACE_READ ();

  if (mmr_off == mmr_offset (mux))
    dv_bfin_mmr_require_32 (me, addr, nr_bytes, false);
  else
    dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);

  switch (mmr_off)
    {
    case mmr_offset(data):
    case mmr_offset(clear):
    case mmr_offset(set):
      dv_store_2 (dest, port->data);
      break;
    case mmr_offset(dir_clear):
    case mmr_offset(dir_set):
      dv_store_2 (dest, port->dir);
      break;
    case mmr_offset(fer):
    case mmr_offset(inen):
      dv_store_2 (dest, *value16p);
      break;
    case mmr_offset(mux):
      dv_store_4 (dest, *value32p);
      break;
    default:
      dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
      break;
    }

  return nr_bytes;
}

static const struct hw_port_descriptor bfin_gpio_ports[] =
{
  { "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);
  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, and it isn't in peripheral mode.  */
  if ((port->dir & bit) || !(port->inen & bit) || !(port->fer & bit))
    {
      HW_TRACE ((me, "ignoring level due to DIR=%i INEN=%i FER=%i",
		 !!(port->dir & bit), !!(port->inen & bit),
		 !!(port->fer & bit)));
      return;
    }

  hw_port_event (me, my_port, level);
}

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_GPIO2_SIZE)
    hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_GPIO2_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_gpio2_descriptor[] =
{
  {"bfin_gpio2", bfin_gpio_finish,},
  {NULL, NULL},
};
