📄 katana.c
字号:
/* Enable access to IPMI ctlr by clearing IPMI PORTSEL bit in CPLD */ reset_out = in_8(cpld_base + KATANA_CPLD_RESET_OUT); reset_out &= ~KATANA_CPLD_RESET_OUT_PORTSEL; out_8(cpld_base + KATANA_CPLD_RESET_OUT, reset_out);}static void __initkatana_setup_arch(void){ if (ppc_md.progress) ppc_md.progress("katana_setup_arch: enter", 0); set_tb(0, 0);#ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) ROOT_DEV = Root_RAM0; else#endif#ifdef CONFIG_ROOT_NFS ROOT_DEV = Root_NFS;#else ROOT_DEV = Root_SDA2;#endif /* * Set up the L2CR register. * * 750FX has only L2E, L2PE (bits 2-8 are reserved) * DD2.0 has bug that requires the L2 to be in WRT mode * avoid dirty data in cache */ if (PVR_REV(mfspr(SPRN_PVR)) == 0x0200) { printk(KERN_INFO "DD2.0 detected. Setting L2 cache" "to Writethrough mode\n"); _set_L2CR(L2CR_L2E | L2CR_L2PE | L2CR_L2WT); } else _set_L2CR(L2CR_L2E | L2CR_L2PE); if (ppc_md.progress) ppc_md.progress("katana_setup_arch: calling setup_bridge", 0); katana_setup_bridge(); katana_setup_peripherals(); katana_enable_ipmi(); katana_bus_frequency = katana_bus_freq(cpld_base); printk(KERN_INFO "Artesyn Communication Products, LLC - Katana(TM)\n"); if (ppc_md.progress) ppc_md.progress("katana_setup_arch: exit", 0);}voidkatana_fixup_resources(struct pci_dev *dev){ u16 v16; pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES>>2); pci_read_config_word(dev, PCI_COMMAND, &v16); v16 |= PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK; pci_write_config_word(dev, PCI_COMMAND, v16);}static const unsigned int cpu_750xx[32] = { /* 750FX & 750GX */ 0, 0, 2, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,/* 0-15*/ 16, 17, 18, 19, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 0 /*16-31*/};static intkatana_get_cpu_freq(void){ unsigned long pll_cfg; pll_cfg = (mfspr(SPRN_HID1) & 0xf8000000) >> 27; return katana_bus_frequency * cpu_750xx[pll_cfg]/2;}/* Platform device data fixup routines. */#if defined(CONFIG_SERIAL_MPSC)static void __initkatana_fixup_mpsc_pdata(struct platform_device *pdev){ struct mpsc_pdata *pdata = (struct mpsc_pdata *)pdev->dev.platform_data; bd_t *bdp = (bd_t *)__res; if (bdp->bi_baudrate) pdata->default_baud = bdp->bi_baudrate; else pdata->default_baud = KATANA_DEFAULT_BAUD; pdata->max_idle = 40; pdata->brg_clk_src = KATANA_MPSC_CLK_SRC; /* * TCLK (not SysCLk) is routed to BRG, then to the MPSC. On most parts, * TCLK == SysCLK but on 64460, they are separate pins. * SysCLK can go up to 200 MHz but TCLK can only go up to 133 MHz. */ pdata->brg_clk_freq = min(katana_bus_frequency, MV64x60_TCLK_FREQ_MAX);}#endif#if defined(CONFIG_MV643XX_ETH)static void __initkatana_fixup_eth_pdata(struct platform_device *pdev){ struct mv643xx_eth_platform_data *eth_pd; static u16 phy_addr[] = { KATANA_ETH0_PHY_ADDR, KATANA_ETH1_PHY_ADDR, KATANA_ETH2_PHY_ADDR, }; eth_pd = pdev->dev.platform_data; eth_pd->force_phy_addr = 1; eth_pd->phy_addr = phy_addr[pdev->id]; eth_pd->tx_queue_size = KATANA_ETH_TX_QUEUE_SIZE; eth_pd->rx_queue_size = KATANA_ETH_RX_QUEUE_SIZE;}#endif#if defined(CONFIG_SYSFS)static void __initkatana_fixup_mv64xxx_pdata(struct platform_device *pdev){ struct mv64xxx_pdata *pdata = (struct mv64xxx_pdata *) pdev->dev.platform_data; /* Katana supports the mv64xxx hotswap register */ pdata->hs_reg_valid = 1;}#endifstatic int __initkatana_platform_notify(struct device *dev){ static struct { char *bus_id; void ((*rtn)(struct platform_device *pdev)); } dev_map[] = {#if defined(CONFIG_SERIAL_MPSC) { MPSC_CTLR_NAME ".0", katana_fixup_mpsc_pdata }, { MPSC_CTLR_NAME ".1", katana_fixup_mpsc_pdata },#endif#if defined(CONFIG_MV643XX_ETH) { MV643XX_ETH_NAME ".0", katana_fixup_eth_pdata }, { MV643XX_ETH_NAME ".1", katana_fixup_eth_pdata }, { MV643XX_ETH_NAME ".2", katana_fixup_eth_pdata },#endif#if defined(CONFIG_SYSFS) { MV64XXX_DEV_NAME ".0", katana_fixup_mv64xxx_pdata },#endif }; struct platform_device *pdev; int i; if (dev && dev->bus_id) for (i=0; i<ARRAY_SIZE(dev_map); i++) if (!strncmp(dev->bus_id, dev_map[i].bus_id, BUS_ID_SIZE)) { pdev = container_of(dev, struct platform_device, dev); dev_map[i].rtn(pdev); } return 0;}#ifdef CONFIG_MTD_PHYSMAP#ifndef MB#define MB (1 << 20)#endif/* * MTD Layout depends on amount of soldered FLASH in system. Sizes in MB. * * FLASH Amount: 128 64 32 16 * ------------- --- -- -- -- * Monitor: 1 1 1 1 * Primary Kernel: 1.5 1.5 1.5 1.5 * Primary fs: 30 30 <end> <end> * Secondary Kernel: 1.5 1.5 N/A N/A * Secondary fs: <end> <end> N/A N/A * User: <overlays entire FLASH except for "Monitor" section> */static int __initkatana_setup_mtd(void){ u32 size; int ptbl_entries; static struct mtd_partition *ptbl; size = katana_flash_size_0 + katana_flash_size_1; if (!size) return -ENOMEM; ptbl_entries = (size >= (64*MB)) ? 6 : 4; if ((ptbl = kmalloc(ptbl_entries * sizeof(struct mtd_partition), GFP_KERNEL)) == NULL) { printk(KERN_WARNING "Can't alloc MTD partition table\n"); return -ENOMEM; } memset(ptbl, 0, ptbl_entries * sizeof(struct mtd_partition)); ptbl[0].name = "Monitor"; ptbl[0].size = KATANA_MTD_MONITOR_SIZE; ptbl[1].name = "Primary Kernel"; ptbl[1].offset = MTDPART_OFS_NXTBLK; ptbl[1].size = 0x00180000; /* 1.5 MB */ ptbl[2].name = "Primary Filesystem"; ptbl[2].offset = MTDPART_OFS_APPEND; ptbl[2].size = MTDPART_SIZ_FULL; /* Correct for 16 & 32 MB */ ptbl[ptbl_entries-1].name = "User FLASH"; ptbl[ptbl_entries-1].offset = KATANA_MTD_MONITOR_SIZE; ptbl[ptbl_entries-1].size = MTDPART_SIZ_FULL; if (size >= (64*MB)) { ptbl[2].size = 30*MB; ptbl[3].name = "Secondary Kernel"; ptbl[3].offset = MTDPART_OFS_NXTBLK; ptbl[3].size = 0x00180000; /* 1.5 MB */ ptbl[4].name = "Secondary Filesystem"; ptbl[4].offset = MTDPART_OFS_APPEND; ptbl[4].size = MTDPART_SIZ_FULL; } physmap_map.size = size; physmap_set_partitions(ptbl, ptbl_entries); return 0;}arch_initcall(katana_setup_mtd);#endifstatic voidkatana_restart(char *cmd){ ulong i = 10000000; /* issue hard reset to the reset command register */ out_8(cpld_base + KATANA_CPLD_RST_CMD, KATANA_CPLD_RST_CMD_HR); while (i-- > 0) ; panic("restart failed\n");}static voidkatana_halt(void){ u8 v; /* Turn on blue LED to indicate its okay to remove */ if (katana_id == KATANA_ID_750I) { u32 v; u8 save_exclude; /* Set LOO bit in cPCI HotSwap reg of hose 0 to turn on LED. */ save_exclude = mv64x60_pci_exclude_bridge; mv64x60_pci_exclude_bridge = 0; early_read_config_dword(bh.hose_a, 0, PCI_DEVFN(0, 0), MV64360_PCICFG_CPCI_HOTSWAP, &v); v &= 0xff; v |= (1 << 19); early_write_config_dword(bh.hose_a, 0, PCI_DEVFN(0, 0), MV64360_PCICFG_CPCI_HOTSWAP, v); mv64x60_pci_exclude_bridge = save_exclude; } else if (katana_id == KATANA_ID_752I) { v = in_8(cpld_base + HSL_PLD_BASE + HSL_PLD_HOT_SWAP_OFF); v |= HSL_PLD_HOT_SWAP_LED_BIT; out_8(cpld_base + HSL_PLD_BASE + HSL_PLD_HOT_SWAP_OFF, v); } while (1) ; /* NOTREACHED */}static voidkatana_power_off(void){ katana_halt(); /* NOTREACHED */}static intkatana_show_cpuinfo(struct seq_file *m){ char *s; seq_printf(m, "cpu freq\t: %dMHz\n", (katana_get_cpu_freq() + 500000) / 1000000); seq_printf(m, "bus freq\t: %ldMHz\n", ((long)katana_bus_frequency + 500000) / 1000000); seq_printf(m, "vendor\t\t: Artesyn Communication Products, LLC\n"); seq_printf(m, "board\t\t: "); switch (katana_id) { case KATANA_ID_3750: seq_printf(m, "Katana 3750"); break; case KATANA_ID_750I: seq_printf(m, "Katana 750i"); break; case KATANA_ID_752I: seq_printf(m, "Katana 752i"); break; default: seq_printf(m, "Unknown"); break; } seq_printf(m, " (product id: 0x%x)\n", in_8(cpld_base + KATANA_CPLD_PRODUCT_ID)); seq_printf(m, "pci mode\t: %sMonarch\n", katana_is_monarch()? "" : "Non-"); seq_printf(m, "hardware rev\t: 0x%x\n", in_8(cpld_base+KATANA_CPLD_HARDWARE_VER)); seq_printf(m, "pld rev\t\t: 0x%x\n", in_8(cpld_base + KATANA_CPLD_PLD_VER)); switch(bh.type) { case MV64x60_TYPE_GT64260A: s = "gt64260a"; break; case MV64x60_TYPE_GT64260B: s = "gt64260b"; break; case MV64x60_TYPE_MV64360: s = "mv64360"; break; case MV64x60_TYPE_MV64460: s = "mv64460"; break; default: s = "Unknown"; } seq_printf(m, "bridge type\t: %s\n", s); seq_printf(m, "bridge rev\t: 0x%x\n", bh.rev);#if defined(CONFIG_NOT_COHERENT_CACHE) seq_printf(m, "coherency\t: %s\n", "off");#else seq_printf(m, "coherency\t: %s\n", "on");#endif return 0;}static void __initkatana_calibrate_decr(void){ u32 freq; freq = katana_bus_frequency / 4; printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n", (long)freq / 1000000, (long)freq % 1000000); tb_ticks_per_jiffy = freq / HZ; tb_to_us = mulhwu_scale_factor(freq, 1000000);}/* * The katana supports both uImage and zImage. If uImage, get the mem size * from the bd info. If zImage, the bootwrapper adds a BI_MEMSIZE entry in * the bi_rec data which is sucked out and put into boot_mem_size by * parse_bootinfo(). MMU_init() will then use the boot_mem_size for the mem * size and not call this routine. The only way this will fail is when a uImage * is used but the fw doesn't pass in a valid bi_memsize. This should never * happen, though. */unsigned long __initkatana_find_end_of_memory(void){ bd_t *bdp = (bd_t *)__res; return bdp->bi_memsize;}#if defined(CONFIG_I2C_MV64XXX) && defined(CONFIG_SENSORS_M41T00)extern ulong m41t00_get_rtc_time(void);extern int m41t00_set_rtc_time(ulong);static int __initkatana_rtc_hookup(void){ struct timespec tv; ppc_md.get_rtc_time = m41t00_get_rtc_time; ppc_md.set_rtc_time = m41t00_set_rtc_time; tv.tv_nsec = 0; tv.tv_sec = (ppc_md.get_rtc_time)(); do_settimeofday(&tv); return 0;}late_initcall(katana_rtc_hookup);#endif#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE)static void __initkatana_map_io(void){ io_block_mapping(0xf8100000, 0xf8100000, 0x00020000, _PAGE_IO);}#endifvoid __initplatform_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7){ parse_bootinfo(find_bootinfo()); /* ASSUMPTION: If both r3 (bd_t pointer) and r6 (cmdline pointer) * are non-zero, then we should use the board info from the bd_t * structure and the cmdline pointed to by r6 instead of the * information from birecs, if any. Otherwise, use the information * from birecs as discovered by the preceeding call to * parse_bootinfo(). This rule should work with both PPCBoot, which * uses a bd_t board info structure, and the kernel boot wrapper, * which uses birecs. */ if (r3 && r6) { /* copy board info structure */ memcpy((void *)__res, (void *)(r3+KERNELBASE), sizeof(bd_t)); /* copy command line */ *(char *)(r7+KERNELBASE) = 0; strcpy(cmd_line, (char *)(r6+KERNELBASE)); }#ifdef CONFIG_BLK_DEV_INITRD /* take care of initrd if we have one */ if (r4) { initrd_start = r4 + KERNELBASE; initrd_end = r5 + KERNELBASE; }#endif /* CONFIG_BLK_DEV_INITRD */ isa_mem_base = 0; ppc_md.setup_arch = katana_setup_arch; ppc_md.pcibios_fixup_resources = katana_fixup_resources; ppc_md.show_cpuinfo = katana_show_cpuinfo; ppc_md.init_IRQ = mv64360_init_irq; ppc_md.get_irq = mv64360_get_irq; ppc_md.restart = katana_restart; ppc_md.power_off = katana_power_off; ppc_md.halt = katana_halt; ppc_md.find_end_of_memory = katana_find_end_of_memory; ppc_md.calibrate_decr = katana_calibrate_decr;#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE) ppc_md.setup_io_mappings = katana_map_io; ppc_md.progress = mv64x60_mpsc_progress; mv64x60_progress_init(CONFIG_MV64X60_NEW_BASE);#endif#if defined(CONFIG_SERIAL_MPSC) || defined(CONFIG_MV643XX_ETH) platform_notify = katana_platform_notify;#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -