/*
* linux/arch/mips/tx4938/toshiba_rbtx4938/setup.c
*
* Setup pointers to hardware-dependent routines.
* Copyright (C) 2000-2001 Toshiba Corporation
*
* 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
* terms of the GNU General Public License version 2. This program is
* licensed "as is" without any warranty of any kind, whether express
* or implied.
*
* Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
*/
#include <linux/init.h>
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/console.h>
#include <linux/pci.h>
#include <linux/pm.h>
#include <linux/platform_device.h>
#include <asm/wbflush.h>
#include <asm/reboot.h>
#include <asm/irq.h>
#include <asm/time.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/bootinfo.h>
#include <asm/tx4938/rbtx4938.h>
#ifdef CONFIG_SERIAL_TXX9
#include <linux/tty.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#endif
extern void rbtx4938_time_init(void) __init;
extern char * __init prom_getcmdline(void);
static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr);
/* These functions are used for rebooting or halting the machine*/
extern void rbtx4938_machine_restart(char *command);
extern void rbtx4938_machine_halt(void);
extern void rbtx4938_machine_power_off(void);
/* clocks */
unsigned int txx9_master_clock;
unsigned int txx9_cpu_clock;
unsigned int txx9_gbus_clock;
unsigned long rbtx4938_ce_base[8];
unsigned long rbtx4938_ce_size[8];
int txboard_pci66_mode;
static int tx4938_pcic_trdyto; /* default: disabled */
static int tx4938_pcic_retryto; /* default: disabled */
static int tx4938_ccfg_toeon = 1;
struct tx4938_pcic_reg *pcicptrs[4] = {
tx4938_pcicptr /* default setting for TX4938 */
};
static struct {
unsigned long base;
unsigned long size;
} phys_regions[16] __initdata;
static int num_phys_regions __initdata;
#define PHYS_REGION_MINSIZE 0x10000
void rbtx4938_machine_halt(void)
{
printk(KERN_NOTICE "System Halted\n");
local_irq_disable();
while (1)
__asm__(".set\tmips3\n\t"
"wait\n\t"
".set\tmips0");
}
void rbtx4938_machine_power_off(void)
{
rbtx4938_machine_halt();
/* no return */
}
void rbtx4938_machine_restart(char *command)
{
local_irq_disable();
printk("Rebooting...");
*rbtx4938_softresetlock_ptr = 1;
*rbtx4938_sfvol_ptr = 1;
*rbtx4938_softreset_ptr = 1;
wbflush();
while(1);
}
void __init
txboard_add_phys_region(unsigned long base, unsigned long size)
{
if (num_phys_regions >= ARRAY_SIZE(phys_regions)) {
printk("phys_region overflow\n");
return;
}
phys_regions[num_phys_regions].base = base;
phys_regions[num_phys_regions].size = size;
num_phys_regions++;
}
unsigned long __init
txboard_find_free_phys_region(unsigned long begin, unsigned long end,
unsigned long size)
{
unsigned long base;
int i;
for (base = begin / size * size; base < end; base += size) {
for (i = 0; i < num_phys_regions; i++) {
if (phys_regions[i].size &&
base <= phys_regions[i].base + (phys_regions[i].size - 1) &&
base + (size - 1) >= phys_regions[i].base)
break;
}
if (i == num_phys_regions)
return base;
}
return 0;
}
unsigned long __init
txboard_find_free_phys_region_shrink(unsigned long begin, unsigned long end,
unsigned long *size)
{
unsigned long sz, base;
for (sz = *size; sz >= PHYS_REGION_MINSIZE; sz /= 2) {
base = txboard_find_free_phys_region(begin, end, sz);
if (base) {
*size = sz;