📄 mv64x60.c
字号:
/* * The 64260B is not supposed to have the bug where the MPSC & ENET * can't access cache coherent regions. However, testing has shown * that the MPSC, at least, still has this bug. */ mv64x60_mpsc0_pdata.cache_mgmt = 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}/* ***************************************************************************** * * MV64360-Specific Routines * ***************************************************************************** *//* * mv64360_translate_size() * * On the MV64360, the size register is set similar to the size you get * from a pci config space BAR register. That is, programmed from LSB to MSB * as a sequence of 1's followed by a sequence of 0's. IOW, "size -1" with the * assumption that the size is a power of 2. */static u32 __initmv64360_translate_size(u32 base_addr, u32 size, u32 num_bits){ return mv64x60_mask(size - 1, num_bits);}/* * mv64360_untranslate_size() * * Translate the size register value of a window into a window size. */static u32 __initmv64360_untranslate_size(u32 base_addr, u32 size, u32 num_bits){ if (size > 0) { size >>= (32 - num_bits); size++; size <<= (32 - num_bits); } return size;}/* * mv64360_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. */struct { u32 fcn; u32 base_hi_bar; u32 base_lo_bar;} static mv64360_reg_addrs[2][4] __initdata = { {{ 0, 0x14, 0x10 }, { 0, 0x1c, 0x18 }, { 1, 0x14, 0x10 }, { 1, 0x1c, 0x18 }}, {{ 0, 0x94, 0x90 }, { 0, 0x9c, 0x98 }, { 1, 0x94, 0x90 }, { 1, 0x9c, 0x98 }}};static void __initmv64360_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, mv64360_reg_addrs[bus][window].fcn), mv64360_reg_addrs[bus][window].base_hi_bar, 0); early_write_config_dword(hose, 0, PCI_DEVFN(0, mv64360_reg_addrs[bus][window].fcn), mv64360_reg_addrs[bus][window].base_lo_bar, mv64x60_mask(base,20) | 0xc); mv64x60_pci_exclude_bridge = save_exclude;}/* * mv64360_set_pci2regs_window() * * Set where the bridge's registers appear in PCI MEM space. */static u32 mv64360_offset[2][2] __initdata = {{0x20, 0x24}, {0xa0, 0xa4}};static void __initmv64360_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), mv64360_offset[bus][0], (base << 16)); early_write_config_dword(hose, 0, PCI_DEVFN(0,0), mv64360_offset[bus][1], 0); mv64x60_pci_exclude_bridge = save_exclude;}/* * mv64360_is_enabled_32bit() * * On a MV64360, a window is enabled by either clearing a bit in the * CPU BAR Enable reg or setting a bit in the window's base reg. * Note that this doesn't work for windows on the PCI slave side but we don't * check those so its okay. */static u32 __initmv64360_is_enabled_32bit(struct mv64x60_handle *bh, u32 window){ u32 extra, rc = 0; if (((mv64360_32bit_windows[window].base_reg != 0) && (mv64360_32bit_windows[window].size_reg != 0)) || (window == MV64x60_CPU2SRAM_WIN)) { extra = mv64360_32bit_windows[window].extra; switch (extra & MV64x60_EXTRA_MASK) { case MV64x60_EXTRA_CPUWIN_ENAB: rc = (mv64x60_read(bh, MV64360_CPU_BAR_ENABLE) & (1 << (extra & 0x1f))) == 0; break; case MV64x60_EXTRA_CPUPROT_ENAB: rc = (mv64x60_read(bh, mv64360_32bit_windows[window].base_reg) & (1 << (extra & 0x1f))) != 0; break; case MV64x60_EXTRA_ENET_ENAB: rc = (mv64x60_read(bh, MV64360_ENET2MEM_BAR_ENABLE) & (1 << (extra & 0x7))) == 0; break; case MV64x60_EXTRA_MPSC_ENAB: rc = (mv64x60_read(bh, MV64360_MPSC2MEM_BAR_ENABLE) & (1 << (extra & 0x3))) == 0; break; case MV64x60_EXTRA_IDMA_ENAB: rc = (mv64x60_read(bh, MV64360_IDMA2MEM_BAR_ENABLE) & (1 << (extra & 0x7))) == 0; break; default: printk(KERN_ERR "mv64360_is_enabled: %s\n", "32bit table corrupted"); } } return rc;}/* * mv64360_enable_window_32bit() * * On a MV64360, a window is enabled by either clearing a bit in the * CPU BAR Enable reg or setting a bit in the window's base reg. */static void __initmv64360_enable_window_32bit(struct mv64x60_handle *bh, u32 window){ u32 extra; pr_debug("enable 32bit window: %d\n", window); if (((mv64360_32bit_windows[window].base_reg != 0) && (mv64360_32bit_windows[window].size_reg != 0)) || (window == MV64x60_CPU2SRAM_WIN)) { extra = mv64360_32bit_windows[window].extra; switch (extra & MV64x60_EXTRA_MASK) { case MV64x60_EXTRA_CPUWIN_ENAB: mv64x60_clr_bits(bh, MV64360_CPU_BAR_ENABLE, (1 << (extra & 0x1f))); break; case MV64x60_EXTRA_CPUPROT_ENAB: mv64x60_set_bits(bh, mv64360_32bit_windows[window].base_reg, (1 << (extra & 0x1f))); break; case MV64x60_EXTRA_ENET_ENAB: mv64x60_clr_bits(bh, MV64360_ENET2MEM_BAR_ENABLE, (1 << (extra & 0x7))); break; case MV64x60_EXTRA_MPSC_ENAB: mv64x60_clr_bits(bh, MV64360_MPSC2MEM_BAR_ENABLE, (1 << (extra & 0x3))); break; case MV64x60_EXTRA_IDMA_ENAB: mv64x60_clr_bits(bh, MV64360_IDMA2MEM_BAR_ENABLE, (1 << (extra & 0x7))); break; default: printk(KERN_ERR "mv64360_enable: %s\n", "32bit table corrupted"); } }}/* * mv64360_disable_window_32bit() * * On a MV64360, a window is disabled by either setting a bit in the * CPU BAR Enable reg or clearing a bit in the window's base reg. */static void __initmv64360_disable_window_32bit(struct mv64x60_handle *bh, u32 window){ u32 extra; pr_debug("disable 32bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n", window, mv64360_32bit_windows[window].base_reg, mv64360_32bit_windows[window].size_reg); if (((mv64360_32bit_windows[window].base_reg != 0) && (mv64360_32bit_windows[window].size_reg != 0)) || (window == MV64x60_CPU2SRAM_WIN)) { extra = mv64360_32bit_windows[window].extra; switch (extra & MV64x60_EXTRA_MASK) { case MV64x60_EXTRA_CPUWIN_ENAB: mv64x60_set_bits(bh, MV64360_CPU_BAR_ENABLE, (1 << (extra & 0x1f))); break; case MV64x60_EXTRA_CPUPROT_ENAB: mv64x60_clr_bits(bh, mv64360_32bit_windows[window].base_reg, (1 << (extra & 0x1f))); break; case MV64x60_EXTRA_ENET_ENAB: mv64x60_set_bits(bh, MV64360_ENET2MEM_BAR_ENABLE, (1 << (extra & 0x7))); break; case MV64x60_EXTRA_MPSC_ENAB: mv64x60_set_bits(bh, MV64360_MPSC2MEM_BAR_ENABLE, (1 << (extra & 0x3))); break; case MV64x60_EXTRA_IDMA_ENAB: mv64x60_set_bits(bh, MV64360_IDMA2MEM_BAR_ENABLE, (1 << (extra & 0x7))); break; default: printk(KERN_ERR "mv64360_disable: %s\n", "32bit table corrupted"); } }}/* * mv64360_enable_window_64bit() * * On the MV64360, a 64-bit window is enabled by setting a bit in the window's * base reg. */static void __initmv64360_enable_window_64bit(struct mv64x60_handle *bh, u32 window){ pr_debug("enable 64bit window: %d\n", window); if ((mv64360_64bit_windows[window].base_lo_reg!= 0) && (mv64360_64bit_windows[window].size_reg != 0)) { if ((mv64360_64bit_windows[window].extra & MV64x60_EXTRA_MASK) == MV64x60_EXTRA_PCIACC_ENAB) mv64x60_set_bits(bh, mv64360_64bit_windows[window].base_lo_reg, (1 << (mv64360_64bit_windows[window].extra & 0x1f))); else printk(KERN_ERR "mv64360_enable: %s\n", "64bit table corrupted"); }}/* * mv64360_disable_window_64bit() * * On a MV64360, a 64-bit window is disabled by clearing a bit in the window's * base reg. */static void __initmv64360_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, mv64360_64bit_windows[window].base_lo_reg, mv64360_64bit_windows[window].size_reg); if ((mv64360_64bit_windows[window].base_lo_reg != 0) && (mv64360_64bit_windows[window].size_reg != 0)) { if ((mv64360_64bit_windows[window].extra & MV64x60_EXTRA_MASK) == MV64x60_EXTRA_PCIACC_ENAB) mv64x60_clr_bits(bh, mv64360_64bit_windows[window].base_lo_reg, (1 << (mv64360_64bit_windows[window].extra & 0x1f))); else printk(KERN_ERR "mv64360_disable: %s\n", "64bit table corrupted"); }}/* * mv64360_disable_all_windows() * * The MV64360 has a few 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 __initmv64360_disable_all_windows(struct mv64x60_handle *bh, struct mv64x60_setup_info *si){ u32 preserve, i; /* 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) mv64360_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))) mv64360_disable_window_64bit(bh, i); /* Turn off PCI->MEM access cntl wins not in mv64360_64bit_windows[] */ mv64x60_clr_bits(bh, MV64x60_PCI0_ACC_CNTL_4_BASE_LO, 0); mv64x60_clr_bits(bh, MV64x60_PCI0_ACC_CNTL_5_BASE_LO, 0); mv64x60_clr_bits(bh, MV64x60_PCI1_ACC_CNTL_4_BASE_LO, 0); mv64x60_clr_bits(bh, MV64x60_PCI1_ACC_CNTL_5_BASE_LO, 0); /* Disable all PCI-><whatever> windows */ mv64x60_set_bits(bh, MV64x60_PCI0_BAR_ENABLE, 0x0000f9ff); mv64x60_set_bits(bh, MV64x60_PCI1_BAR_ENABLE, 0x0000f9ff);}/* * mv64360_config_io2mem_windows() * * ENET, MPSC, and IDMA ctlrs on the MV64[34]60 have separate windows that * must be set up so that the respective ctlr can access system memory. */static u32 enet_tab[MV64x60_CPU2MEM_WINDOWS] __initdata = { MV64x60_ENET2MEM_0_WIN, MV64x60_ENET2MEM_1_WIN, MV64x60_ENET2MEM_2_WIN, MV64x60_ENET2MEM_3_WIN,};static u32 mpsc_tab[MV64x60_CPU2MEM_WINDOWS] __initdata = { MV64x60_MPSC2MEM_0_WIN, MV64x60_MPSC2MEM_1_WIN, MV64x60_MPSC2MEM_2_WIN, MV64x60_MPSC2MEM_3_WIN,};static u32 idma_tab[MV64x60_CPU2MEM_WINDOWS] __initdata = { MV64x60_IDMA2MEM_0_WIN, MV64x60_IDMA2MEM_1_WIN, MV64x60_IDMA2MEM_2_WIN, MV64x60_IDMA2MEM_3_WIN,};static u32 dram_selects[MV64x60_CPU2MEM_WINDOWS] __initdata = { 0xe, 0xd, 0xb, 0x7 };static void __initmv64360_config_io2mem_windows(struct mv64x60_handle *bh, struct mv64x60_setup_info *si, u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]){ u32 i, win; pr_debug("config_io2regs_windows: enet, mpsc, idma -> bridge regs\n"); mv64x60_write(bh, MV64360_ENET2MEM_ACC_PROT_0, 0); mv64x60_write(bh, MV64360_ENET2MEM_ACC_PROT_1, 0); mv64x60_write(bh, MV64360_ENET2MEM_ACC_PROT_2, 0); mv64x60_write(bh, MV64360_MPSC2MEM_ACC_PROT_0, 0); mv64x60_write(bh, MV64360_MPSC2MEM_ACC_PROT_1, 0); mv64x60_write(bh, MV64360_IDMA2MEM_ACC_PROT_0, 0); mv64x60_write(bh, MV64360_IDMA2MEM_ACC_PROT_1, 0); mv64x60_write(bh, MV64360_IDMA2MEM_ACC_PROT_2, 0); mv64x60_write(bh, MV64360_IDMA2MEM_ACC_PROT_3, 0); /* Assume that mem ctlr has no more windows than embedded I/O ctlr */ for (win=MV64x60_CPU2MEM_0_WIN,i=0;win<=MV64x60_CPU2MEM_3_WIN;win++,i++) if (bh->ci->is_enabled_32bit(bh, win)) { mv64x60_set_32bit_window(bh, enet_tab[i], mem_windows[i][0], mem_windows[i][1], (dram_selects[i] << 8) | (si->enet_options[i] & 0x3000)); bh->ci->enable_window_32bit(bh, enet_tab[i]); /* Give enet r/w access to memory region */ mv64x60_set_bits(bh, MV64360_ENET2MEM_ACC_PROT_0, (0x3 << (i << 1))); mv64x60_set_bits(bh, MV64360_ENET2MEM_ACC_PROT_1, (0x3 << (i << 1))); mv64x60_set_bits(bh, MV64360_ENET2MEM_ACC_PROT_2, (0x3 << (i << 1))); mv64x60_set_32bit_window(bh, mpsc_tab[i], mem_windows[i][0], mem_windows[i][1], (dram_selects[i] << 8) | (si->mpsc_options[i] & 0x3000)); bh->ci->enable_window_32bit(bh, mpsc_tab[i]); /* Give mpsc r/w access to memory region */ mv64x60_set_bits(bh, MV64360_MPSC2MEM_ACC_PROT_0, (0x3 << (i << 1))); mv64x60_set_bits(bh, MV64360_MPSC2MEM_ACC_PROT_1, (0x3 << (i << 1))); mv64x60_set_32bit_window(bh, idma_tab[i], mem_windows[i][0], mem_windows[i][1], (dram_selects[i] << 8) | (si->idma_options[i] & 0x3000)); bh->ci->enable_window_32bit(bh, idma_tab[i]); /* Give idma r/w access to memory region */ mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_0, (0x3 << (i << 1)));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -