📄 mv64x60.c
字号:
{ struct pci_controller *hose; hose = pci_bus_to_hose(bus); /* Skip slot 0 on both hoses */ if ((mv64x60_pci_exclude_bridge == 1) && (PCI_SLOT(devfn) == 0) && (hose->first_busno == bus)) return PCIBIOS_DEVICE_NOT_FOUND; else return PCIBIOS_SUCCESSFUL;} /* mv64x60_pci_exclude_device() *//* ***************************************************************************** * * Platform Device Routines * ***************************************************************************** *//* * mv64x60_pd_fixup() * * Need to add the base addr of where the bridge's regs are mapped in the * physical addr space so drivers can ioremap() them. */void __initmv64x60_pd_fixup(struct mv64x60_handle *bh, struct platform_device *pd_devs[], u32 entries){ struct resource *r; u32 i, j; for (i=0; i<entries; i++) { j = 0; while ((r = platform_get_resource(pd_devs[i],IORESOURCE_MEM,j)) != NULL) { r->start += bh->p_base; r->end += bh->p_base; j++; } }}/* * mv64x60_add_pds() * * Add the mv64x60 platform devices to the list of platform devices. */static int __initmv64x60_add_pds(void){ return platform_add_devices(mv64x60_pd_devs, ARRAY_SIZE(mv64x60_pd_devs));}arch_initcall(mv64x60_add_pds);/* ***************************************************************************** * * GT64260-Specific Routines * ***************************************************************************** *//* * gt64260_translate_size() * * On the GT64260, the size register is really the "top" address of the window. */static u32 __initgt64260_translate_size(u32 base, u32 size, u32 num_bits){ return base + mv64x60_mask(size - 1, num_bits);}/* * gt64260_untranslate_size() * * Translate the top address of a window into a window size. */static u32 __initgt64260_untranslate_size(u32 base, u32 size, u32 num_bits){ if (size >= base) size = size - base + (1 << (32 - num_bits)); else size = 0; return size;}/* * gt64260_set_pci2mem_window() * * The PCI->MEM window registers are actually in PCI config space so need * to set them by setting the correct config space BARs. */static u32 gt64260_reg_addrs[2][4] __initdata = { { 0x10, 0x14, 0x18, 0x1c }, { 0x90, 0x94, 0x98, 0x9c }};static void __initgt64260_set_pci2mem_window(struct pci_controller *hose, u32 bus, u32 window, u32 base){ u8 save_exclude; pr_debug("set pci->mem window: %d, hose: %d, base: 0x%x\n", window, hose->index, base); save_exclude = mv64x60_pci_exclude_bridge; mv64x60_pci_exclude_bridge = 0; early_write_config_dword(hose, 0, PCI_DEVFN(0, 0), gt64260_reg_addrs[bus][window], mv64x60_mask(base, 20) | 0x8); mv64x60_pci_exclude_bridge = save_exclude;}/* * gt64260_set_pci2regs_window() * * Set where the bridge's registers appear in PCI MEM space. */static u32 gt64260_offset[2] __initdata = {0x20, 0xa0};static void __initgt64260_set_pci2regs_window(struct mv64x60_handle *bh, struct pci_controller *hose, u32 bus, u32 base){ u8 save_exclude; pr_debug("set pci->internal regs hose: %d, base: 0x%x\n", hose->index, base); save_exclude = mv64x60_pci_exclude_bridge; mv64x60_pci_exclude_bridge = 0; early_write_config_dword(hose, 0, PCI_DEVFN(0,0), gt64260_offset[bus], (base << 16)); mv64x60_pci_exclude_bridge = save_exclude;}/* * gt64260_is_enabled_32bit() * * On a GT64260, a window is enabled iff its top address is >= to its base * address. */static u32 __initgt64260_is_enabled_32bit(struct mv64x60_handle *bh, u32 window){ u32 rc = 0; if ((gt64260_32bit_windows[window].base_reg != 0) && (gt64260_32bit_windows[window].size_reg != 0) && ((mv64x60_read(bh, gt64260_32bit_windows[window].size_reg) & ((1 << gt64260_32bit_windows[window].size_bits) - 1)) >= (mv64x60_read(bh, gt64260_32bit_windows[window].base_reg) & ((1 << gt64260_32bit_windows[window].base_bits) - 1)))) rc = 1; return rc;}/* * gt64260_enable_window_32bit() * * On the GT64260, a window is enabled iff the top address is >= to the base * address of the window. Since the window has already been configured by * the time this routine is called, we have nothing to do here. */static void __initgt64260_enable_window_32bit(struct mv64x60_handle *bh, u32 window){ pr_debug("enable 32bit window: %d\n", window);}/* * gt64260_disable_window_32bit() * * On a GT64260, you disable a window by setting its top address to be less * than its base address. */static void __initgt64260_disable_window_32bit(struct mv64x60_handle *bh, u32 window){ pr_debug("disable 32bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n", window, gt64260_32bit_windows[window].base_reg, gt64260_32bit_windows[window].size_reg); if ((gt64260_32bit_windows[window].base_reg != 0) && (gt64260_32bit_windows[window].size_reg != 0)) { /* To disable, make bottom reg higher than top reg */ mv64x60_write(bh, gt64260_32bit_windows[window].base_reg,0xfff); mv64x60_write(bh, gt64260_32bit_windows[window].size_reg, 0); }}/* * gt64260_enable_window_64bit() * * On the GT64260, a window is enabled iff the top address is >= to the base * address of the window. Since the window has already been configured by * the time this routine is called, we have nothing to do here. */static void __initgt64260_enable_window_64bit(struct mv64x60_handle *bh, u32 window){ pr_debug("enable 64bit window: %d\n", window);}/* * gt64260_disable_window_64bit() * * On a GT64260, you disable a window by setting its top address to be less * than its base address. */static void __initgt64260_disable_window_64bit(struct mv64x60_handle *bh, u32 window){ pr_debug("disable 64bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n", window, gt64260_64bit_windows[window].base_lo_reg, gt64260_64bit_windows[window].size_reg); if ((gt64260_64bit_windows[window].base_lo_reg != 0) && (gt64260_64bit_windows[window].size_reg != 0)) { /* To disable, make bottom reg higher than top reg */ mv64x60_write(bh, gt64260_64bit_windows[window].base_lo_reg, 0xfff); mv64x60_write(bh, gt64260_64bit_windows[window].base_hi_reg, 0); mv64x60_write(bh, gt64260_64bit_windows[window].size_reg, 0); }}/* * gt64260_disable_all_windows() * * The GT64260 has several windows that aren't represented in the table of * windows at the top of this file. This routine turns all of them off * except for the memory controller windows, of course. */static void __initgt64260_disable_all_windows(struct mv64x60_handle *bh, struct mv64x60_setup_info *si){ u32 i, preserve; /* Disable 32bit windows (don't disable cpu->mem windows) */ for (i=MV64x60_CPU2DEV_0_WIN; i<MV64x60_32BIT_WIN_COUNT; i++) { if (i < 32) preserve = si->window_preserve_mask_32_lo & (1 << i); else preserve = si->window_preserve_mask_32_hi & (1<<(i-32)); if (!preserve) gt64260_disable_window_32bit(bh, i); } /* Disable 64bit windows */ for (i=0; i<MV64x60_64BIT_WIN_COUNT; i++) if (!(si->window_preserve_mask_64 & (1<<i))) gt64260_disable_window_64bit(bh, i); /* Turn off cpu protection windows not in gt64260_32bit_windows[] */ mv64x60_write(bh, GT64260_CPU_PROT_BASE_4, 0xfff); mv64x60_write(bh, GT64260_CPU_PROT_SIZE_4, 0); mv64x60_write(bh, GT64260_CPU_PROT_BASE_5, 0xfff); mv64x60_write(bh, GT64260_CPU_PROT_SIZE_5, 0); mv64x60_write(bh, GT64260_CPU_PROT_BASE_6, 0xfff); mv64x60_write(bh, GT64260_CPU_PROT_SIZE_6, 0); mv64x60_write(bh, GT64260_CPU_PROT_BASE_7, 0xfff); mv64x60_write(bh, GT64260_CPU_PROT_SIZE_7, 0); /* Turn off PCI->MEM access cntl wins not in gt64260_64bit_windows[] */ mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_4_BASE_LO, 0xfff); mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_4_BASE_HI, 0); mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_4_SIZE, 0); mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_5_BASE_LO, 0xfff); mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_5_BASE_HI, 0); mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_5_SIZE, 0); mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_6_BASE_LO, 0xfff); mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_6_BASE_HI, 0); mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_6_SIZE, 0); mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_7_BASE_LO, 0xfff); mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_7_BASE_HI, 0); mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_7_SIZE, 0); mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_4_BASE_LO, 0xfff); mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_4_BASE_HI, 0); mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_4_SIZE, 0); mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_5_BASE_LO, 0xfff); mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_5_BASE_HI, 0); mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_5_SIZE, 0); mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_6_BASE_LO, 0xfff); mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_6_BASE_HI, 0); mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_6_SIZE, 0); mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_7_BASE_LO, 0xfff); mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_7_BASE_HI, 0); mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_7_SIZE, 0); /* Disable all PCI-><whatever> windows */ mv64x60_set_bits(bh, MV64x60_PCI0_BAR_ENABLE, 0x07fffdff); mv64x60_set_bits(bh, MV64x60_PCI1_BAR_ENABLE, 0x07fffdff); /* * Some firmwares enable a bunch of intr sources * for the PCI INT output pins. */ mv64x60_write(bh, GT64260_IC_CPU_INTR_MASK_LO, 0); mv64x60_write(bh, GT64260_IC_CPU_INTR_MASK_HI, 0); mv64x60_write(bh, GT64260_IC_PCI0_INTR_MASK_LO, 0); mv64x60_write(bh, GT64260_IC_PCI0_INTR_MASK_HI, 0); mv64x60_write(bh, GT64260_IC_PCI1_INTR_MASK_LO, 0); mv64x60_write(bh, GT64260_IC_PCI1_INTR_MASK_HI, 0); mv64x60_write(bh, GT64260_IC_CPU_INT_0_MASK, 0); mv64x60_write(bh, GT64260_IC_CPU_INT_1_MASK, 0); mv64x60_write(bh, GT64260_IC_CPU_INT_2_MASK, 0); mv64x60_write(bh, GT64260_IC_CPU_INT_3_MASK, 0);}/* * gt64260a_chip_specific_init() * * Implement errata work arounds for the GT64260A. */static void __initgt64260a_chip_specific_init(struct mv64x60_handle *bh, struct mv64x60_setup_info *si){#ifdef CONFIG_SERIAL_MPSC struct resource *r;#endif#if !defined(CONFIG_NOT_COHERENT_CACHE) u32 val; u8 save_exclude;#endif if (si->pci_0.enable_bus) mv64x60_set_bits(bh, MV64x60_PCI0_CMD, ((1<<4) | (1<<5) | (1<<9) | (1<<13))); if (si->pci_1.enable_bus) mv64x60_set_bits(bh, MV64x60_PCI1_CMD, ((1<<4) | (1<<5) | (1<<9) | (1<<13))); /* * Dave Wilhardt found that bit 4 in the PCI Command registers must * be set if you are using cache coherency. */#if !defined(CONFIG_NOT_COHERENT_CACHE) /* Res #MEM-4 -- cpu read buffer to buffer 1 */ if ((mv64x60_read(bh, MV64x60_CPU_MODE) & 0xf0) == 0x40) mv64x60_set_bits(bh, GT64260_SDRAM_CONFIG, (1<<26)); save_exclude = mv64x60_pci_exclude_bridge; mv64x60_pci_exclude_bridge = 0; if (si->pci_0.enable_bus) { early_read_config_dword(bh->hose_a, 0, PCI_DEVFN(0,0), PCI_COMMAND, &val); val |= PCI_COMMAND_INVALIDATE; early_write_config_dword(bh->hose_a, 0, PCI_DEVFN(0,0), PCI_COMMAND, val); } if (si->pci_1.enable_bus) { early_read_config_dword(bh->hose_b, 0, PCI_DEVFN(0,0), PCI_COMMAND, &val); val |= PCI_COMMAND_INVALIDATE; early_write_config_dword(bh->hose_b, 0, PCI_DEVFN(0,0), PCI_COMMAND, val); } mv64x60_pci_exclude_bridge = save_exclude;#endif /* Disable buffer/descriptor snooping */ mv64x60_clr_bits(bh, 0xf280, (1<< 6) | (1<<14) | (1<<22) | (1<<30)); mv64x60_clr_bits(bh, 0xf2c0, (1<< 6) | (1<<14) | (1<<22) | (1<<30));#ifdef CONFIG_SERIAL_MPSC mv64x60_mpsc0_pdata.mirror_regs = 1; mv64x60_mpsc0_pdata.cache_mgmt = 1; mv64x60_mpsc1_pdata.mirror_regs = 1; mv64x60_mpsc1_pdata.cache_mgmt = 1; if ((r = platform_get_resource(&mpsc1_device, IORESOURCE_IRQ, 0)) != NULL) { r->start = MV64x60_IRQ_SDMA_0; r->end = MV64x60_IRQ_SDMA_0; }#endif}/* * gt64260b_chip_specific_init() * * Implement errata work arounds for the GT64260B. */static void __initgt64260b_chip_specific_init(struct mv64x60_handle *bh, struct mv64x60_setup_info *si){#ifdef CONFIG_SERIAL_MPSC struct resource *r;#endif#if !defined(CONFIG_NOT_COHERENT_CACHE) u32 val; u8 save_exclude;#endif if (si->pci_0.enable_bus) mv64x60_set_bits(bh, MV64x60_PCI0_CMD, ((1<<4) | (1<<5) | (1<<9) | (1<<13))); if (si->pci_1.enable_bus) mv64x60_set_bits(bh, MV64x60_PCI1_CMD, ((1<<4) | (1<<5) | (1<<9) | (1<<13))); /* * Dave Wilhardt found that bit 4 in the PCI Command registers must * be set if you are using cache coherency. */#if !defined(CONFIG_NOT_COHERENT_CACHE) mv64x60_set_bits(bh, GT64260_CPU_WB_PRIORITY_BUFFER_DEPTH, 0xf); /* Res #MEM-4 -- cpu read buffer to buffer 1 */ if ((mv64x60_read(bh, MV64x60_CPU_MODE) & 0xf0) == 0x40) mv64x60_set_bits(bh, GT64260_SDRAM_CONFIG, (1<<26)); save_exclude = mv64x60_pci_exclude_bridge; mv64x60_pci_exclude_bridge = 0; if (si->pci_0.enable_bus) { early_read_config_dword(bh->hose_a, 0, PCI_DEVFN(0,0), PCI_COMMAND, &val); val |= PCI_COMMAND_INVALIDATE; early_write_config_dword(bh->hose_a, 0, PCI_DEVFN(0,0), PCI_COMMAND, val); } if (si->pci_1.enable_bus) { early_read_config_dword(bh->hose_b, 0, PCI_DEVFN(0,0), PCI_COMMAND, &val); val |= PCI_COMMAND_INVALIDATE; early_write_config_dword(bh->hose_b, 0, PCI_DEVFN(0,0), PCI_COMMAND, val); } mv64x60_pci_exclude_bridge = save_exclude;#endif /* Disable buffer/descriptor snooping */ mv64x60_clr_bits(bh, 0xf280, (1<< 6) | (1<<14) | (1<<22) | (1<<30)); mv64x60_clr_bits(bh, 0xf2c0, (1<< 6) | (1<<14) | (1<<22) | (1<<30));#ifdef CONFIG_SERIAL_MPSC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -