katana.c

来自「h内核」· C语言 代码 · 共 685 行 · 第 1/2 页

C
685
字号
/* * arch/ppc/platforms/katana.c * * Board setup routines for the Artesyn Katana 750 based boards. * * Tim Montgomery <timm@artesyncp.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. *//* * Supports the Artesyn 750i, 752i, and 3750.  The 752i is virtually identical * to the 750i except that it has an mv64460 bridge. */#include <linux/config.h>#include <linux/kernel.h>#include <linux/pci.h>#include <linux/kdev_t.h>#include <linux/console.h>#include <linux/initrd.h>#include <linux/root_dev.h>#include <linux/delay.h>#include <linux/seq_file.h>#include <linux/smp.h>#include <linux/mv643xx.h>#ifdef CONFIG_BOOTIMG#include <linux/bootimg.h>#endif#include <asm/page.h>#include <asm/time.h>#include <asm/smp.h>#include <asm/todc.h>#include <asm/bootinfo.h>#include <asm/mv64x60.h>#include <platforms/katana.h>static struct		mv64x60_handle bh;static katana_id_t	katana_id;static u32		cpld_base;static u32		sram_base;/* PCI Interrupt routing */static int __initkatana_irq_lookup_750i(unsigned char idsel, unsigned char pin){	static char pci_irq_table[][4] = {		/*		 * PCI IDSEL/INTPIN->INTLINE		 *       A   B   C   D		 */		/* IDSEL 4  (PMC 1) */		{ KATANA_PCI_INTB_IRQ_750i, KATANA_PCI_INTC_IRQ_750i,			KATANA_PCI_INTD_IRQ_750i, KATANA_PCI_INTA_IRQ_750i },		/* IDSEL 5  (PMC 2) */		{ KATANA_PCI_INTC_IRQ_750i, KATANA_PCI_INTD_IRQ_750i,			KATANA_PCI_INTA_IRQ_750i, KATANA_PCI_INTB_IRQ_750i },		/* IDSEL 6 (T8110) */		{KATANA_PCI_INTD_IRQ_750i, 0, 0, 0 },	};	const long min_idsel = 4, max_idsel = 6, irqs_per_slot = 4;	return PCI_IRQ_TABLE_LOOKUP;}static int __initkatana_irq_lookup_3750(unsigned char idsel, unsigned char pin){	static char pci_irq_table[][4] = {		/*		 * PCI IDSEL/INTPIN->INTLINE		 *       A   B   C   D		 */		{ KATANA_PCI_INTA_IRQ_3750, 0, 0, 0 }, /* IDSEL 3 (BCM5691) */		{ KATANA_PCI_INTB_IRQ_3750, 0, 0, 0 }, /* IDSEL 4 (MV64360 #2)*/		{ KATANA_PCI_INTC_IRQ_3750, 0, 0, 0 }, /* IDSEL 5 (MV64360 #3)*/	};	const long min_idsel = 3, max_idsel = 5, irqs_per_slot = 4;	return PCI_IRQ_TABLE_LOOKUP;}static int __initkatana_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin){	switch (katana_id) {	case KATANA_ID_750I:	case KATANA_ID_752I:		return katana_irq_lookup_750i(idsel, pin);	case KATANA_ID_3750:		return katana_irq_lookup_3750(idsel, pin);	default:		printk(KERN_ERR "Bogus board ID\n");		return 0;	}}/* Board info retrieval routines */void __initkatana_get_board_id(void){	switch (in_8((volatile char *)(cpld_base + KATANA_CPLD_PRODUCT_ID))) {	case KATANA_PRODUCT_ID_3750:		katana_id = KATANA_ID_3750;		break;	case KATANA_PRODUCT_ID_750i:		katana_id = KATANA_ID_750I;		break;	case KATANA_PRODUCT_ID_752i:		katana_id = KATANA_ID_752I;		break;	default:		printk(KERN_ERR "Unsupported board\n");	}}int __initkatana_get_proc_num(void){	u16		val;	u8		save_exclude;	static int	proc = -1;	static u8	first_time = 1;	if (first_time) {		if (katana_id != KATANA_ID_3750)			proc = 0;		else {			save_exclude = mv64x60_pci_exclude_bridge;			mv64x60_pci_exclude_bridge = 0;			early_read_config_word(bh.hose_a, 0,				PCI_DEVFN(0,0), PCI_DEVICE_ID, &val);			mv64x60_pci_exclude_bridge = save_exclude;			switch(val) {			case PCI_DEVICE_ID_KATANA_3750_PROC0:				proc = 0;				break;			case PCI_DEVICE_ID_KATANA_3750_PROC1:				proc = 1;				break;			case PCI_DEVICE_ID_KATANA_3750_PROC2:				proc = 2;				break;			default:				printk(KERN_ERR "Bogus Device ID\n");			}		}		first_time = 0;	}	return proc;}static inline intkatana_is_monarch(void){	return in_8((volatile char *)(cpld_base + KATANA_CPLD_BD_CFG_3)) &		KATANA_CPLD_BD_CFG_3_MONARCH;}static void __initkatana_enable_ipmi(void){	u8 reset_out;	/* Enable access to IPMI ctlr by clearing IPMI PORTSEL bit in CPLD */	reset_out = in_8((volatile char *)(cpld_base + KATANA_CPLD_RESET_OUT));	reset_out &= ~KATANA_CPLD_RESET_OUT_PORTSEL;	out_8((volatile void *)(cpld_base + KATANA_CPLD_RESET_OUT), reset_out);	return;}static unsigned longkatana_bus_freq(void){	u8 bd_cfg_0;	bd_cfg_0 = in_8((volatile char *)(cpld_base + KATANA_CPLD_BD_CFG_0));	switch (bd_cfg_0 & KATANA_CPLD_BD_CFG_0_SYSCLK_MASK) {	case KATANA_CPLD_BD_CFG_0_SYSCLK_200:		return 200000000;		break;	case KATANA_CPLD_BD_CFG_0_SYSCLK_166:		return 166666666;		break;	case KATANA_CPLD_BD_CFG_0_SYSCLK_133:		return 133333333;		break;	case KATANA_CPLD_BD_CFG_0_SYSCLK_100:		return 100000000;		break;	default:		return 133333333;		break;	}}/* Bridge & platform setup routines */void __initkatana_intr_setup(void){	/* MPP 8, 9, and 10 */	mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_1, 0xfff);	/* MPP 14 */	if ((katana_id == KATANA_ID_750I) || (katana_id == KATANA_ID_752I))		mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_1, 0x0f000000);	/*	 * Define GPP 8,9,and 10 interrupt polarity as active low	 * input signal and level triggered	 */	mv64x60_set_bits(&bh, MV64x60_GPP_LEVEL_CNTL, 0x700);	mv64x60_clr_bits(&bh, MV64x60_GPP_IO_CNTL, 0x700);	if ((katana_id == KATANA_ID_750I) || (katana_id == KATANA_ID_752I)) {		mv64x60_set_bits(&bh, MV64x60_GPP_LEVEL_CNTL, (1<<14));		mv64x60_clr_bits(&bh, MV64x60_GPP_IO_CNTL, (1<<14));	}	/* Config GPP intr ctlr to respond to level trigger */	mv64x60_set_bits(&bh, MV64x60_COMM_ARBITER_CNTL, (1<<10));	/* 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, ~0x700);	mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK, 0x700);	if ((katana_id == KATANA_ID_750I) || (katana_id == KATANA_ID_752I)) {		mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, ~(1<<14));		mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK, (1<<14));	}	/*	 * Dismiss and then enable interrupt on CPU #0 high cause reg	 * BIT25 summarizes GPP interrupts 8-15	 */	mv64x60_set_bits(&bh, MV64360_IC_CPU0_INTR_MASK_HI, (1<<25));	return;}void __initkatana_setup_peripherals(void){	u32 base, size_0, size_1;	/* Set up windows for boot CS, soldered & socketed flash, and CPLD */	mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN,		 KATANA_BOOT_WINDOW_BASE, KATANA_BOOT_WINDOW_SIZE, 0);	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN);	/* Assume firmware set up window sizes correctly for dev 0 & 1 */	mv64x60_get_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN, &base, &size_0);	if (size_0 > 0) {		mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN,			 KATANA_SOLDERED_FLASH_BASE, size_0, 0);		bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_0_WIN);	}	mv64x60_get_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN, &base, &size_1);	if (size_1 > 0) {		mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN,			 (KATANA_SOLDERED_FLASH_BASE + size_0), size_1, 0);		bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN);	}	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN,		 KATANA_SOCKET_BASE, KATANA_SOCKETED_FLASH_SIZE, 0);	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN);	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN,		 KATANA_CPLD_BASE, KATANA_CPLD_SIZE, 0);	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_3_WIN);	cpld_base = (u32)ioremap(KATANA_CPLD_BASE, KATANA_CPLD_SIZE);	mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN,		 KATANA_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, 0);	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);	sram_base = (u32)ioremap(KATANA_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE);	/* Set up Enet->SRAM window */	mv64x60_set_32bit_window(&bh, MV64x60_ENET2MEM_4_WIN,		KATANA_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, 0x2);	bh.ci->enable_window_32bit(&bh, MV64x60_ENET2MEM_4_WIN);	/* Give enet r/w access to memory region */	mv64x60_set_bits(&bh, MV64360_ENET2MEM_ACC_PROT_0, (0x3 << (4 << 1)));	mv64x60_set_bits(&bh, MV64360_ENET2MEM_ACC_PROT_1, (0x3 << (4 << 1)));	mv64x60_set_bits(&bh, MV64360_ENET2MEM_ACC_PROT_2, (0x3 << (4 << 1)));	mv64x60_clr_bits(&bh, MV64x60_PCI1_PCI_DECODE_CNTL, (1 << 3));	mv64x60_clr_bits(&bh, MV64x60_TIMR_CNTR_0_3_CNTL,			 ((1 << 0) | (1 << 8) | (1 << 16) | (1 << 24)));	/* Must wait until window set up before retrieving board id */	katana_get_board_id();	/* Enumerate pci bus (must know board id before getting proc number) */	if (katana_get_proc_num() == 0)		bh.hose_b->last_busno = pciauto_bus_scan(bh.hose_b, 0);#if defined(CONFIG_NOT_COHERENT_CACHE)	mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x00160000);#else	mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x001600b2);#endif	/*	 * Setting the SRAM to 0. Note that this generates parity errors on	 * internal data path in SRAM since it's first time accessing it	 * while after reset it's not configured.	 */	memset((void *)sram_base, 0, MV64360_SRAM_SIZE);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?