📄 radstone_ppc7d.c
字号:
/* * arch/ppc/platforms/radstone_ppc7d.c * * Board setup routines for the Radstone PPC7D boards. * * Author: James Chapman <jchapman@katalix.com> * * Based on code done by Rabeeh Khoury - rabeeh@galileo.co.il * Based on code done by - Mark A. Greer <mgreer@mvista.com> * * 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. *//* Radstone PPC7D boards are rugged VME boards with PPC 7447A CPUs, * Discovery-II, dual gigabit ethernet, dual PMC, USB, keyboard/mouse, * 4 serial ports, 2 high speed serial ports (MPSCs) and optional * SCSI / VGA. */#include <linux/config.h>#include <linux/stddef.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/errno.h>#include <linux/reboot.h>#include <linux/pci.h>#include <linux/kdev_t.h>#include <linux/major.h>#include <linux/initrd.h>#include <linux/console.h>#include <linux/delay.h>#include <linux/ide.h>#include <linux/seq_file.h>#include <linux/root_dev.h>#include <linux/serial.h>#include <linux/tty.h> /* for linux/serial_core.h */#include <linux/serial_core.h>#include <linux/mv643xx.h>#include <linux/netdevice.h>#include <linux/platform_device.h>#include <asm/system.h>#include <asm/pgtable.h>#include <asm/page.h>#include <asm/time.h>#include <asm/dma.h>#include <asm/io.h>#include <asm/machdep.h>#include <asm/prom.h>#include <asm/smp.h>#include <asm/vga.h>#include <asm/open_pic.h>#include <asm/i8259.h>#include <asm/todc.h>#include <asm/bootinfo.h>#include <asm/mpc10x.h>#include <asm/pci-bridge.h>#include <asm/mv64x60.h>#include "radstone_ppc7d.h"#undef DEBUG#define PPC7D_RST_PIN 17 /* GPP17 */extern u32 mv64360_irq_base;extern spinlock_t rtc_lock;static struct mv64x60_handle bh;static int ppc7d_has_alma;extern void gen550_progress(char *, unsigned short);extern void gen550_init(int, struct uart_port *);/* FIXME - move to h file */extern int ds1337_do_command(int id, int cmd, void *arg);#define DS1337_GET_DATE 0#define DS1337_SET_DATE 1/* residual data */unsigned char __res[sizeof(bd_t)];/***************************************************************************** * Serial port code *****************************************************************************/#if defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG)static void __init ppc7d_early_serial_map(void){#if defined(CONFIG_SERIAL_MPSC_CONSOLE) mv64x60_progress_init(CONFIG_MV64X60_NEW_BASE);#elif defined(CONFIG_SERIAL_8250) struct uart_port serial_req; /* Setup serial port access */ memset(&serial_req, 0, sizeof(serial_req)); serial_req.uartclk = UART_CLK; serial_req.irq = 4; serial_req.flags = STD_COM_FLAGS; serial_req.iotype = SERIAL_IO_MEM; serial_req.membase = (u_char *) PPC7D_SERIAL_0; gen550_init(0, &serial_req); if (early_serial_setup(&serial_req) != 0) printk(KERN_ERR "Early serial init of port 0 failed\n"); /* Assume early_serial_setup() doesn't modify serial_req */ serial_req.line = 1; serial_req.irq = 3; serial_req.membase = (u_char *) PPC7D_SERIAL_1; gen550_init(1, &serial_req); if (early_serial_setup(&serial_req) != 0) printk(KERN_ERR "Early serial init of port 1 failed\n");#else#error CONFIG_KGDB || CONFIG_SERIAL_TEXT_DEBUG has no supported CONFIG_SERIAL_XXX#endif}#endif /* CONFIG_KGDB || CONFIG_SERIAL_TEXT_DEBUG *//***************************************************************************** * Low-level board support code *****************************************************************************/static unsigned long __init ppc7d_find_end_of_memory(void){ bd_t *bp = (bd_t *) __res; if (bp->bi_memsize) return bp->bi_memsize; return (256 * 1024 * 1024);}static void __init ppc7d_map_io(void){ /* remove temporary mapping */ mtspr(SPRN_DBAT3U, 0x00000000); mtspr(SPRN_DBAT3L, 0x00000000); io_block_mapping(0xe8000000, 0xe8000000, 0x08000000, _PAGE_IO); io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO);}static void ppc7d_restart(char *cmd){ u32 data; /* Disable GPP17 interrupt */ data = mv64x60_read(&bh, MV64x60_GPP_INTR_MASK); data &= ~(1 << PPC7D_RST_PIN); mv64x60_write(&bh, MV64x60_GPP_INTR_MASK, data); /* Configure MPP17 as GPP */ data = mv64x60_read(&bh, MV64x60_MPP_CNTL_2); data &= ~(0x0000000f << 4); mv64x60_write(&bh, MV64x60_MPP_CNTL_2, data); /* Enable pin GPP17 for output */ data = mv64x60_read(&bh, MV64x60_GPP_IO_CNTL); data |= (1 << PPC7D_RST_PIN); mv64x60_write(&bh, MV64x60_GPP_IO_CNTL, data); /* Toggle GPP9 pin to reset the board */ mv64x60_write(&bh, MV64x60_GPP_VALUE_CLR, 1 << PPC7D_RST_PIN); mv64x60_write(&bh, MV64x60_GPP_VALUE_SET, 1 << PPC7D_RST_PIN); for (;;) ; /* Spin until reset happens */ /* NOTREACHED */}static void ppc7d_power_off(void){ u32 data; local_irq_disable(); /* Ensure that internal MV643XX watchdog is disabled. * The Disco watchdog uses MPP17 on this hardware. */ data = mv64x60_read(&bh, MV64x60_MPP_CNTL_2); data &= ~(0x0000000f << 4); mv64x60_write(&bh, MV64x60_MPP_CNTL_2, data); data = mv64x60_read(&bh, MV64x60_WDT_WDC); if (data & 0x80000000) { mv64x60_write(&bh, MV64x60_WDT_WDC, 1 << 24); mv64x60_write(&bh, MV64x60_WDT_WDC, 2 << 24); } for (;;) ; /* No way to shut power off with software */ /* NOTREACHED */}static void ppc7d_halt(void){ ppc7d_power_off(); /* NOTREACHED */}static unsigned long ppc7d_led_no_pulse;static int __init ppc7d_led_pulse_disable(char *str){ ppc7d_led_no_pulse = 1; return 1;}/* This kernel option disables the heartbeat pulsing of a board LED */__setup("ledoff", ppc7d_led_pulse_disable);static void ppc7d_heartbeat(void){ u32 data32; u8 data8; static int max706_wdog = 0; /* Unfortunately we can't access the LED control registers * during early init because they're on the CPLD which is the * other side of a PCI bridge which goes unreachable during * PCI scan. So write the LEDs only if the MV64360 watchdog is * enabled (i.e. userspace apps are running so kernel is up).. */ data32 = mv64x60_read(&bh, MV64x60_WDT_WDC); if (data32 & 0x80000000) { /* Enable MAX706 watchdog if not done already */ if (!max706_wdog) { outb(3, PPC7D_CPLD_RESET); max706_wdog = 1; } /* Hit the MAX706 watchdog */ outb(0, PPC7D_CPLD_WATCHDOG_TRIG); /* Pulse LED DS219 if not disabled */ if (!ppc7d_led_no_pulse) { static int led_on = 0; data8 = inb(PPC7D_CPLD_LEDS); if (led_on) data8 &= ~PPC7D_CPLD_LEDS_DS219_MASK; else data8 |= PPC7D_CPLD_LEDS_DS219_MASK; outb(data8, PPC7D_CPLD_LEDS); led_on = !led_on; } } ppc_md.heartbeat_count = ppc_md.heartbeat_reset;}static int ppc7d_show_cpuinfo(struct seq_file *m){ u8 val; u8 val1, val2; static int flash_sizes[4] = { 64, 32, 0, 16 }; static int flash_banks[4] = { 4, 3, 2, 1 }; static int sdram_bank_sizes[4] = { 128, 256, 512, 1 }; int sdram_num_banks = 2; static char *pci_modes[] = { "PCI33", "PCI66", "Unknown", "Unknown", "PCIX33", "PCIX66", "PCIX100", "PCIX133" }; seq_printf(m, "vendor\t\t: Radstone Technology\n"); seq_printf(m, "machine\t\t: PPC7D\n"); val = inb(PPC7D_CPLD_BOARD_REVISION); val1 = (val & PPC7D_CPLD_BOARD_REVISION_NUMBER_MASK) >> 5; val2 = (val & PPC7D_CPLD_BOARD_REVISION_LETTER_MASK); seq_printf(m, "revision\t: %hd%c%c\n", val1, (val2 <= 0x18) ? 'A' + val2 : 'Y', (val2 > 0x18) ? 'A' + (val2 - 0x19) : ' '); val = inb(PPC7D_CPLD_MOTHERBOARD_TYPE); val1 = val & PPC7D_CPLD_MB_TYPE_PLL_MASK; val2 = val & (PPC7D_CPLD_MB_TYPE_ECC_FITTED_MASK | PPC7D_CPLD_MB_TYPE_ECC_ENABLE_MASK); seq_printf(m, "bus speed\t: %dMHz\n", (val1 == PPC7D_CPLD_MB_TYPE_PLL_133) ? 133 : (val1 == PPC7D_CPLD_MB_TYPE_PLL_100) ? 100 : (val1 == PPC7D_CPLD_MB_TYPE_PLL_64) ? 64 : 0); val = inb(PPC7D_CPLD_MEM_CONFIG); if (val & PPC7D_CPLD_SDRAM_BANK_NUM_MASK) sdram_num_banks--; val = inb(PPC7D_CPLD_MEM_CONFIG_EXTEND); val1 = (val & PPC7D_CPLD_SDRAM_BANK_SIZE_MASK) >> 6; seq_printf(m, "SDRAM\t\t: %d banks of %d%c, total %d%c", sdram_num_banks, sdram_bank_sizes[val1], (sdram_bank_sizes[val1] < 128) ? 'G' : 'M', sdram_num_banks * sdram_bank_sizes[val1], (sdram_bank_sizes[val1] < 128) ? 'G' : 'M'); if (val2 & PPC7D_CPLD_MB_TYPE_ECC_FITTED_MASK) { seq_printf(m, " [ECC %sabled]", (val2 & PPC7D_CPLD_MB_TYPE_ECC_ENABLE_MASK) ? "en" : "dis"); } seq_printf(m, "\n"); val1 = (val & PPC7D_CPLD_FLASH_DEV_SIZE_MASK); val2 = (val & PPC7D_CPLD_FLASH_BANK_NUM_MASK) >> 2; seq_printf(m, "FLASH\t\t: %d banks of %dM, total %dM\n", flash_banks[val2], flash_sizes[val1], flash_banks[val2] * flash_sizes[val1]); val = inb(PPC7D_CPLD_FLASH_WRITE_CNTL); val1 = inb(PPC7D_CPLD_SW_FLASH_WRITE_PROTECT); seq_printf(m, " write links\t: %s%s%s%s\n", (val & PPD7D_CPLD_FLASH_CNTL_WR_LINK_MASK) ? "WRITE " : "", (val & PPD7D_CPLD_FLASH_CNTL_BOOT_LINK_MASK) ? "BOOT " : "", (val & PPD7D_CPLD_FLASH_CNTL_USER_LINK_MASK) ? "USER " : "", (val & (PPD7D_CPLD_FLASH_CNTL_WR_LINK_MASK | PPD7D_CPLD_FLASH_CNTL_BOOT_LINK_MASK | PPD7D_CPLD_FLASH_CNTL_USER_LINK_MASK)) == 0 ? "NONE" : ""); seq_printf(m, " write sector h/w enables: %s%s%s%s%s\n", (val & PPD7D_CPLD_FLASH_CNTL_RECO_WR_MASK) ? "RECOVERY " : "", (val & PPD7D_CPLD_FLASH_CNTL_BOOT_WR_MASK) ? "BOOT " : "", (val & PPD7D_CPLD_FLASH_CNTL_USER_WR_MASK) ? "USER " : "", (val1 & PPC7D_CPLD_FLASH_CNTL_NVRAM_PROT_MASK) ? "NVRAM " : "", (((val & (PPD7D_CPLD_FLASH_CNTL_RECO_WR_MASK | PPD7D_CPLD_FLASH_CNTL_BOOT_WR_MASK | PPD7D_CPLD_FLASH_CNTL_BOOT_WR_MASK)) == 0) && ((val1 & PPC7D_CPLD_FLASH_CNTL_NVRAM_PROT_MASK) == 0)) ? "NONE" : ""); val1 = inb(PPC7D_CPLD_SW_FLASH_WRITE_PROTECT) & (PPC7D_CPLD_SW_FLASH_WRPROT_SYSBOOT_MASK | PPC7D_CPLD_SW_FLASH_WRPROT_USER_MASK); seq_printf(m, " software sector enables: %s%s%s\n", (val1 & PPC7D_CPLD_SW_FLASH_WRPROT_SYSBOOT_MASK) ? "SYSBOOT " : "", (val1 & PPC7D_CPLD_SW_FLASH_WRPROT_USER_MASK) ? "USER " : "", (val1 == 0) ? "NONE " : ""); seq_printf(m, "Boot options\t: %s%s%s%s\n", (val & PPC7D_CPLD_FLASH_CNTL_ALTBOOT_LINK_MASK) ? "ALTERNATE " : "", (val & PPC7D_CPLD_FLASH_CNTL_VMEBOOT_LINK_MASK) ? "VME " : "", (val & PPC7D_CPLD_FLASH_CNTL_RECBOOT_LINK_MASK) ? "RECOVERY " : "", ((val & (PPC7D_CPLD_FLASH_CNTL_ALTBOOT_LINK_MASK | PPC7D_CPLD_FLASH_CNTL_VMEBOOT_LINK_MASK | PPC7D_CPLD_FLASH_CNTL_RECBOOT_LINK_MASK)) == 0) ? "NONE" : ""); val = inb(PPC7D_CPLD_EQUIPMENT_PRESENT_1); seq_printf(m, "Fitted modules\t: %s%s%s%s\n", (val & PPC7D_CPLD_EQPT_PRES_1_PMC1_MASK) ? "" : "PMC1 ", (val & PPC7D_CPLD_EQPT_PRES_1_PMC2_MASK) ? "" : "PMC2 ", (val & PPC7D_CPLD_EQPT_PRES_1_AFIX_MASK) ? "AFIX " : "", ((val & (PPC7D_CPLD_EQPT_PRES_1_PMC1_MASK | PPC7D_CPLD_EQPT_PRES_1_PMC2_MASK | PPC7D_CPLD_EQPT_PRES_1_AFIX_MASK)) == (PPC7D_CPLD_EQPT_PRES_1_PMC1_MASK | PPC7D_CPLD_EQPT_PRES_1_PMC2_MASK)) ? "NONE" : ""); if (val & PPC7D_CPLD_EQPT_PRES_1_AFIX_MASK) { static const char *ids[] = { "unknown", "1553 (Dual Channel)", "1553 (Single Channel)", "8-bit SCSI + VGA",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -