/* Gaisler AMBA Plug&Play bus scanning. Functions
 * ending on _nomem is inteded to be used only during
 * initialization, only registers are used (no ram).
 *
 * (C) Copyright 2007
 * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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 2 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <command.h>
#include <ambapp.h>

#if defined(CONFIG_CMD_AMBAPP)
extern void ambapp_print_apb(apbctrl_pp_dev * apb,
			     ambapp_ahbdev * apbmst, int index);
extern void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index);
extern int ambapp_apb_print;
extern int ambapp_ahb_print;
#endif

static int ambapp_apb_scan(unsigned int vendor,	/* Plug&Play Vendor ID */
			   unsigned int driver,	/* Plug&Play Device ID */
			   ambapp_apbdev * dev,	/* Result(s) is placed here */
			   int index,	/* Index of device to start copying Plug&Play
					 * info into dev
					 */
			   int max_cnt	/* Maximal count that dev can hold, if dev
					 * is NULL function will stop scanning after
					 * max_cnt devices are found.
					 */
    )
{
	int i, cnt = 0;
	unsigned int apbmst_base;
	ambapp_ahbdev apbmst;
	apbctrl_pp_dev *apb;

	if (max_cnt == 0)
		return 0;

	/* Get AMBA APB Master */
	if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_APBMST, &apbmst) != 1) {
		return 0;
	}

	/* Get APB CTRL Plug&Play info area */
	apbmst_base = apbmst.address[0] & LEON3_IO_AREA;
	apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA);

	for (i = 0; i < LEON3_APB_SLAVES; i++) {
#if defined(CONFIG_CMD_AMBAPP)
		if (ambapp_apb_print && amba_vendor(apb->conf)
		    && amba_device(apb->conf)) {
			ambapp_print_apb(apb, &apbmst, i);
		}
#endif
		if ((amba_vendor(apb->conf) == vendor) &&
		    (amba_device(apb->conf) == driver) && ((index < 0)
							   || (index-- == 0))) {
			/* Convert Plug&Play info into a more readable format */
			cnt++;
			if (dev) {
				dev->irq = amba_irq(apb->conf);
				dev->ver = amba_ver(apb->conf);
				dev->address =
				    (apbmst_base |
				     (((apb->
					bar & 0xfff00000) >> 12))) & (((apb->
									bar &
									0x0000fff0)
								       << 4) |
								      0xfff00000);
				dev++;
			}
			/* found max devices? */
			if (cnt >= max_cnt)
				return cnt;
		}
		/* Get next Plug&Play entry */
		apb++;
	}
	return cnt;
}

unsigned int ambapp_apb_next_nomem(register unsigned int vendor,	/* Plug&Play Vendor ID */
				   register unsigned int driver,	/* Plug&Play Device ID */
				   register int index)
{
	register int i;
	register ahbctrl_pp_dev *apbmst;
	register apbctrl_pp_dev *apb;
	register unsigned int apbmst_base;

	/* APBMST is a AHB Slave */
	apbmst = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0);
	if (!apbmst)
		return 0;

	apbmst_base = amba_membar_start(apbmst->bars[0]);
	if (amba_membar_type(apbmst->bars[0]) == AMBA_TYPE_AHBIO)
		apbmst_base = AMBA_TYPE_AHBIO_ADDR(apbmst_base);
	apbmst_base &= LEON3_IO_AREA;

	/* Find the vendor/driver device on the first APB bus */
	apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA);

	for (i = 0; i < LEON3_APB_SLAVES; i++) {
		if ((amba_vendor(apb->conf) == vendor) &&
		    (amba_device(apb->conf) == driver) && ((index < 0)
							   || (index-- == 0))) {
			/* Convert Plug&Play info info a more readable format */
			return (apbmst_base | (((apb->bar & 0xfff00000) >> 12)))
			    & (((apb->bar & 0x0000fff0) << 4) | 0xfff00000);
		}
		/* Get next Plug&Play entry */
		apb++;
	}
	return 0;
}

/****************************** APB SLAVES ******************************/

int ambapp_apb_count(unsigned int vendor, unsigned int driver)
{
	return ambapp_apb_scan(vendor, driver, NULL, 0, LEON3_APB_SLAVES);
}

int ambapp_apb_first(unsigned int vendor,
		     unsigned int driver, ambapp_apbdev * dev)
{
	return ambapp_apb_scan(vendor, driver, dev, 0, 1);
}

int ambapp_apb_next(unsigned int vendor,
		    unsigned int driver, ambapp_apbdev * dev, int index)
{
	return ambapp_apb_scan(vendor, driver, dev, index, 1);
}

int ambapp_apbs_first(unsigned int vendor,
		      unsigned int driver, ambapp_apbdev * dev, int max_cnt)
{
	return ambapp_apb_scan(vendor, driver, dev, 0, max_cnt);
}

enum {
	AHB_SCAN_MASTER = 0,
	AHB_SCAN_SLAVE = 1
};

/* Scan AMBA Plug&Play bus for AMBA AHB Masters or AHB Slaves
 * for a certain matching Vendor and Device ID.
 *
 * Return number of devices found.
 *
 * Compact edition...
 */
static int ambapp_ahb_scan(unsigned int vendor,	/* Plug&Play Vendor ID */
			   unsigned int driver,	/* Plug&Play Device ID */
			   ambapp_ahbdev * dev,	/* Result(s) is placed here */
			   int index,	/* Index of device to start copying Plug&Play
					 * info into dev
					 */
			   int max_cnt,	/* Maximal count that dev can hold, if dev
					 * is NULL function will stop scanning after
					 * max_cnt devices are found.
					 */
			   int type	/* Selectes what type of devices to scan.
					 * 0=AHB Masters
					 * 1=AHB Slaves
					 */
    )
{
	int i, j, cnt = 0, max_pp_devs;
	unsigned int addr;
	ahbctrl_info *info = (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA);
	ahbctrl_pp_dev *ahb;

	if (max_cnt == 0)
		return 0;

	if (type == 0) {
		max_pp_devs = LEON3_AHB_MASTERS;
		ahb = info->masters;
	} else {
		max_pp_devs = LEON3_AHB_SLAVES;
		ahb = info->slaves;
	}

	for (i = 0; i < max_pp_devs; i++) {
#if defined(CONFIG_CMD_AMBAPP)
		if (ambapp_ahb_print && amba_vendor(ahb->conf) &&
		    amba_device(ahb->conf)) {
			ambapp_print_ahb(ahb, i);
		}
#endif
		if ((amba_vendor(ahb->conf) == vendor) &&
		    (amba_device(ahb->conf) == driver) &&
		    ((index < 0) || (index-- == 0))) {
			/* Convert Plug&Play info info a more readable format */
			cnt++;
			if (dev) {
				dev->irq = amba_irq(ahb->conf);
				dev->ver = amba_ver(ahb->conf);
				dev->userdef[0] = ahb->userdef[0];
				dev->userdef[1] = ahb->userdef[1];
				dev->userdef[2] = ahb->userdef[2];
				for (j = 0; j < 4; j++) {
					addr = amba_membar_start(ahb->bars[j]);
					if (amba_membar_type(ahb->bars[j]) ==
					    AMBA_TYPE_AHBIO)
						addr =
						    AMBA_TYPE_AHBIO_ADDR(addr);
					dev->address[j] = addr;
				}
				dev++;
			}
			/* found max devices? */
			if (cnt >= max_cnt)
				return cnt;
		}
		/* Get next Plug&Play entry */
		ahb++;
	}
	return cnt;
}

unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info)
{
	register unsigned int ret;

	if (!ahb)
		return 0;

	switch (info) {
	default:
		info = 0;
	case 0:
	case 1:
	case 2:
	case 3:
		/* Get Address from PnP Info */
		ret = amba_membar_start(ahb->bars[info]);
		if (amba_membar_type(ahb->bars[info]) == AMBA_TYPE_AHBIO)
			ret = AMBA_TYPE_AHBIO_ADDR(ret);
		return ret;
	}
	return 0;

}

ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor,	/* Plug&Play Vendor ID */
				      register unsigned int driver,	/* Plug&Play Device ID */
				      register unsigned int opts,	/* 1=slave, 0=master */
				      register int index)
{
	register ahbctrl_pp_dev *ahb;
	register ahbctrl_info *info =
	    (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA);
	register int i;
	register int max_pp_devs;

	if (opts == 0) {
		max_pp_devs = LEON3_AHB_MASTERS;
		ahb = info->masters;
	} else {
		max_pp_devs = LEON3_AHB_SLAVES;
		ahb = info->slaves;
	}

	for (i = 0; i < max_pp_devs; i++) {
		if ((amba_vendor(ahb->conf) == vendor) &&
		    (amba_device(ahb->conf) == driver) &&
		    ((index < 0) || (index-- == 0))) {
			/* Convert Plug&Play info info a more readable format */
			return ahb;
		}
		/* Get next Plug&Play entry */
		ahb++;
	}
	return 0;
}

/****************************** AHB MASTERS ******************************/
int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver)
{
	/* Get number of devices of this vendor&device ID */
	return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_MASTERS,
			       AHB_SCAN_MASTER);
}

int ambapp_ahbmst_first(unsigned int vendor, unsigned int driver,
			ambapp_ahbdev * dev)
{
	/* find first device of this */
	return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_MASTER);
}

int ambapp_ahbmst_next(unsigned int vendor,
		       unsigned int driver, ambapp_ahbdev * dev, int index)
{
	/* find first device of this */
	return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_MASTER);
}

int ambapp_ahbmsts_first(unsigned int vendor,
			 unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
{
	/* find first device of this */
	return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt,
			       AHB_SCAN_MASTER);
}

/****************************** AHB SLAVES ******************************/
int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver)
{
	/* Get number of devices of this vendor&device ID */
	return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_SLAVES,
			       AHB_SCAN_SLAVE);
}

int ambapp_ahbslv_first(unsigned int vendor, unsigned int driver,
			ambapp_ahbdev * dev)
{
	/* find first device of this */
	return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_SLAVE);
}

int ambapp_ahbslv_next(unsigned int vendor,
		       unsigned int driver, ambapp_ahbdev * dev, int index)
{
	/* find first device of this */
	return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_SLAVE);
}

int ambapp_ahbslvs_first(unsigned int vendor,
			 unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
{
	/* find first device of this */
	return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt, AHB_SCAN_SLAVE);
}
