/*
 * IBM Summit-Specific Code
 *
 * Written By: Matthew Dobson, IBM Corporation
 *
 * Copyright (c) 2003 IBM Corp.
 *
 * All rights reserved.
 *
 * 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, GOOD TITLE or
 * NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * Send feedback to <colpatch@us.ibm.com>
 *
 */

#include <linux/mm.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/mach-summit/mach_mpparse.h>

static struct rio_table_hdr *rio_table_hdr __initdata;
static struct scal_detail   *scal_devs[MAX_NUMNODES] __initdata;
static struct rio_detail    *rio_devs[MAX_NUMNODES*4] __initdata;

static int __init setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus)
{
	int twister = 0, node = 0;
	int i, bus, num_buses;

	for(i = 0; i < rio_table_hdr->num_rio_dev; i++){
		if (rio_devs[i]->node_id == rio_devs[wpeg_num]->owner_id){
			twister = rio_devs[i]->owner_id;
			break;
		}
	}
	if (i == rio_table_hdr->num_rio_dev){
		printk(KERN_ERR "%s: Couldn't find owner Cyclone for Winnipeg!\n", __FUNCTION__);
		return last_bus;
	}

	for(i = 0; i < rio_table_hdr->num_scal_dev; i++){
		if (scal_devs[i]->node_id == twister){
			node = scal_devs[i]->node_id;
			break;
		}
	}
	if (i == rio_table_hdr->num_scal_dev){
		printk(KERN_ERR "%s: Couldn't find owner Twister for Cyclone!\n", __FUNCTION__);
		return last_bus;
	}

	switch (rio_devs[wpeg_num]->type){
	case CompatWPEG:
		/* The Compatibility Winnipeg controls the 2 legacy buses,
		 * the 66MHz PCI bus [2 slots] and the 2 "extra" buses in case
		 * a PCI-PCI bridge card is used in either slot: total 5 buses.
		 */
		num_buses = 5;
		break;
	case AltWPEG:
		/* The Alternate Winnipeg controls the 2 133MHz buses [1 slot
		 * each], their 2 "extra" buses, the 100MHz bus [2 slots] and
		 * the "extra" buses for each of those slots: total 7 buses.
		 */
		num_buses = 7;
		break;
	case LookOutAWPEG:
	case LookOutBWPEG:
		/* A Lookout Winnipeg controls 3 100MHz buses [2 slots each]
		 * & the "extra" buses for each of those slots: total 9 buses.
		 */
		num_buses = 9;
		break;
	default:
		printk(KERN_INFO "%s: Unsupported Winnipeg type!\n", __FUNCTION__);
		return last_bus;
	}

	for(bus = last_bus; bus < last_bus + num_buses; bus++)
		mp_bus_id_to_node[bus] = node;
	return bus;
}

static int __init build_detail_arrays(void)
{
	unsigned long ptr;
	int i, scal_detail_size, rio_detail_size;

	if (rio_table_hdr->num_scal_dev > MAX_NUMNODES){
		printk(KERN_WARNING "%s: MAX_NUMNODES too low!  Defined as %d, but system has %d nodes.\n", __FUNCTION__, MAX_NUMNODES, rio_table_hdr->num_scal_dev);
		return 0;
	}

	switch (rio_table_hdr->version){
	default:
		printk(KERN_WARNING "%s: Invalid Rio Grande Table Version: %d\n", __FUNCTION__, rio_table_hdr->version);
		return 0;
	case 2:
		scal_detail_size = 11;
		rio_detail_size = 13;
		break;
	case 3:
		scal_detail_size = 12;
		rio_detail_size = 15;
		break;
	}

	ptr = (unsigned long)rio_table_hdr + 3;
	for(i = 0; i < rio_table_hdr->num_scal_dev; i++, ptr += scal_detail_size)
		scal_devs[i] = (struct scal_detail *)ptr;

	for(i = 0; i < rio_table_hdr->num_rio_dev; i++, ptr += rio_detail_size)
		rio_devs[i] = (struct rio_detail *)ptr;

	return 1;
}

void __init setup_summit(void)
{
	unsigned long		ptr;
	unsigned short		offset;
	int			i, next_wpeg, next_bus = 0;

	/* The pointer to the EBDA is stored in the word @ phys 0x40E(40:0E) */
	ptr = *(unsigned short *)phys_to_virt(0x40Eul);
	ptr = (unsigned long)phys_to_virt(ptr << 4);

	rio_table_hdr = NULL;
	offset = 0x180;
	while (offset){
		/* The block id is stored in the 2nd word */
		if (*((unsigned short *)(ptr + offset + 2)) == 0x4752){
			/* set the pointer past the offset & block id */
			rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4);
			break;
		}
		/* The next offset is stored in the 1st word.  0 means no more */
		offset = *((unsigned short *)(ptr + offset));
	}
	if (!rio_table_hdr){
		printk(KERN_ERR "%s: Unable to locate Rio Grande Table in EBDA - bailing!\n", __FUNCTION__);
		return;
	}

	if (!build_detail_arrays())
		return;

	/* The first Winnipeg we're looking for has an index of 0 */
	next_wpeg = 0;
	do {
		for(i = 0; i < rio_table_hdr->num_rio_dev; i++){
			if (is_WPEG(rio_devs[i]) && rio_devs[i]->WP_index == next_wpeg){
				/* It's the Winnipeg we're looking for! */
				next_bus = setup_pci_node_map_for_wpeg(i, next_bus);
				next_wpeg++;
				break;
			}
		}
		/*
		 * If we go through all Rio devices and don't find one with
		 * the next index, it means we've found all the Winnipegs,
		 * and thus all the PCI buses.
		 */
		if (i == rio_table_hdr->num_rio_dev)
			next_wpeg = 0;
	} while (next_wpeg != 0);
}
