/*
* Board setup routines for the Sky Computers HDPU Compute Blade.
*
* Written by Brian Waite <waite@skycomputers.com>
*
* Based on code done by - Mark A. Greer <mgreer@mvista.com>
* Rabeeh Khoury - rabeeh@galileo.co.il
*
* 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.
*/
#include <linux/config.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/ide.h>
#include <linux/seq_file.h>
#include <linux/platform_device.h>
#include <linux/initrd.h>
#include <linux/root_dev.h>
#include <linux/smp.h>
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/todc.h>
#include <asm/mv64x60.h>
#include <asm/ppcboot.h>
#include <platforms/hdpu.h>
#include <linux/mv643xx.h>
#include <linux/hdpu_features.h>
#include <linux/device.h>
#include <linux/mtd/physmap.h>
#define BOARD_VENDOR "Sky Computers"
#define BOARD_MACHINE "HDPU-CB-A"
bd_t ppcboot_bd;
int ppcboot_bd_valid = 0;
static mv64x60_handle_t bh;
extern char cmd_line[];
unsigned long hdpu_find_end_of_memory(void);
void hdpu_mpsc_progress(char *s, unsigned short hex);
void hdpu_heartbeat(void);
static void parse_bootinfo(unsigned long r3,
unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7);
static void hdpu_set_l1pe(void);
static void hdpu_cpustate_set(unsigned char new_state);
#ifdef CONFIG_SMP
static DEFINE_SPINLOCK(timebase_lock);
static unsigned int timebase_upper = 0, timebase_lower = 0;
extern int smp_tb_synchronized;
void __devinit hdpu_tben_give(void);
void __devinit hdpu_tben_take(void);
#endif
static int __init
hdpu_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
{
struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
if (hose->index == 0) {
static char pci_irq_table[][4] = {
{HDPU_PCI_0_IRQ, 0, 0, 0},
{HDPU_PCI_0_IRQ, 0, 0, 0},
};
const long min_idsel = 1, max_idsel = 2, irqs_per_slot = 4;
return PCI_IRQ_TABLE_LOOKUP;
} else {
static char pci_irq_table[][4] = {
{HDPU_PCI_1_IRQ, 0, 0, 0},
};
const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
return PCI_IRQ_TABLE_LOOKUP;
}
}
static void __init hdpu_intr_setup(void)
{
mv64x60_write(&bh, MV64x60_GPP_IO_CNTL,
(1 | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) |
(1 << 6) | (1 << 7) | (1 << 12) | (1 << 16) |
(1 << 18) | (1 << 19) | (1 << 20) | (1 << 21) |
(1 << 22) | (1 << 23) | (1 << 24) | (1 << 25) |
(1 << 26) | (1 << 27) | (1 << 28) | (1 << 29)));
/* XXXX Erranum FEr PCI-#8 */
mv64x60_clr_bits(&bh, MV64x60_PCI0_CMD, (1 << 5) | (1 << 9));
mv64x60_clr_bits(&bh, MV64x60_PCI1_CMD, (1 << 5) | (1 << 9));
/*
* Dismiss and then enable interrupt on GPP interrupt cause
* for CPU #0
*/
mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, ~((1 << 8) | (1 << 13)));
mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK,