X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fppc%2Fsyslib%2Fmv64x60.c;h=b06c8c762bb7931e3f5259aafb5085aec897f291;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=c31fe5330637871c8008da28dcf11c876f2cf179;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c index c31fe5330..b06c8c762 100644 --- a/arch/ppc/syslib/mv64x60.c +++ b/arch/ppc/syslib/mv64x60.c @@ -1,13 +1,12 @@ /* * arch/ppc/syslib/mv64x60.c - * + * * Common routines for the Marvell/Galileo Discovery line of host bridges - * (e.g, gt64260 and mv64360). + * (gt64260, mv64360, mv64460, ...). * * Author: Mark A. Greer - * Rabeeh Khoury * - * 2001-2002 (c) MontaVista, Software, Inc. This file is licensed under + * 2004 (c) MontaVista, Software, Inc. This file is licensed under * the terms of the GNU General Public License version 2. This program * is licensed "as is" without any warranty of any kind, whether express * or implied. @@ -18,6 +17,9 @@ #include #include #include +#include +#include +#include #include #include @@ -25,627 +27,68 @@ #include #include #include -#include #include -#include - +#include -#undef DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif /* DEBUG */ +u8 mv64x60_pci_exclude_bridge = 1; +spinlock_t mv64x60_lock = SPIN_LOCK_UNLOCKED; - -static u32 mv64x60_mask(u32 val, u32 num_bits); -static u32 mv64x60_shift_left(u32 val, u32 num_bits); -static u32 mv64x60_shift_right(u32 val, u32 num_bits); -static void mv64x60_early_init(mv64x60_handle_t *bh, mv64x60_setup_info_t *si); -static int mv64x60_get_type(mv64x60_handle_t *bh); -static int mv64x60_setup_for_chip(mv64x60_handle_t *bh); -static void mv64x60_get_mem_windows(mv64x60_handle_t *bh, - u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]); -static u32 mv64x60_calc_mem_size(mv64x60_handle_t *bh, - u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]); -static void mv64x60_config_cpu2mem_windows(mv64x60_handle_t *bh, - mv64x60_setup_info_t *si, u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]); -static void mv64x60_config_cpu2pci_windows(mv64x60_handle_t *bh, - mv64x60_setup_info_t *si); -static void mv64x60_set_cpu2pci_window(mv64x60_handle_t *bh, - mv64x60_pci_info_t *pi, u32 *win_tab, u32 *remap_tab); -static void mv64x60_config_pci2mem_windows(mv64x60_handle_t *bh, - mv64x60_setup_info_t *si, u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]); -static void mv64x60_alloc_hoses(mv64x60_handle_t *bh, mv64x60_setup_info_t *si); -static void mv64x60_init_hoses(mv64x60_handle_t *bh, mv64x60_setup_info_t *si); -static void mv64x60_init_resources(struct pci_controller *hose, - mv64x60_pci_info_t *pi, u32 io_base); -static void mv64x60_set_pci_params(struct pci_controller *hose, - mv64x60_pci_info_t *pi); -static void mv64x60_enumerate_buses(mv64x60_handle_t *bh, - mv64x60_setup_info_t *si); -static int mv64x60_pci_exclude_device(u8 bus, u8 devfn); -static void mv64x60_fixup_ocp(struct ocp_device *, void *arg); +static phys_addr_t mv64x60_bridge_pbase = 0; +static void *mv64x60_bridge_vbase = 0; +static u32 mv64x60_bridge_type = MV64x60_TYPE_INVALID; +static u32 mv64x60_bridge_rev = 0; static u32 gt64260_translate_size(u32 base, u32 size, u32 num_bits); static u32 gt64260_untranslate_size(u32 base, u32 size, u32 num_bits); -static void gt64260_set_pci2mem_window(struct pci_controller *hose, +static void gt64260_set_pci2mem_window(struct pci_controller *hose, u32 bus, u32 window, u32 base); -static u32 gt64260_is_enabled_32bit(mv64x60_handle_t *bh, u32 window); -static void gt64260_enable_window_32bit(mv64x60_handle_t *bh, u32 window); -static void gt64260_disable_window_32bit(mv64x60_handle_t *bh, u32 window); -static void gt64260_enable_window_64bit(mv64x60_handle_t *bh, u32 window); -static void gt64260_disable_window_64bit(mv64x60_handle_t *bh, u32 window); -static void gt64260_disable_all_windows(mv64x60_handle_t *bh, - mv64x60_setup_info_t *si); -static void gt64260a_chip_specific_init(mv64x60_handle_t *bh, - mv64x60_setup_info_t *si); -static void gt64260b_chip_specific_init(mv64x60_handle_t *bh, - mv64x60_setup_info_t *si); - -static u32 mv64360_translate_size(u32 base_addr, u32 size, u32 num_bits); -static u32 mv64360_untranslate_size(u32 base_addr, u32 size, u32 num_bits); -static void mv64360_set_pci2mem_window(struct pci_controller *hose, +static void gt64260_set_pci2regs_window(struct mv64x60_handle *bh, + struct pci_controller *hose, u32 bus, u32 base); +static u32 gt64260_is_enabled_32bit(struct mv64x60_handle *bh, u32 window); +static void gt64260_enable_window_32bit(struct mv64x60_handle *bh, u32 window); +static void gt64260_disable_window_32bit(struct mv64x60_handle *bh, u32 window); +static void gt64260_enable_window_64bit(struct mv64x60_handle *bh, u32 window); +static void gt64260_disable_window_64bit(struct mv64x60_handle *bh, u32 window); +static void gt64260_disable_all_windows(struct mv64x60_handle *bh, + struct mv64x60_setup_info *si); +static void gt64260a_chip_specific_init(struct mv64x60_handle *bh, + struct mv64x60_setup_info *si); +static void gt64260b_chip_specific_init(struct mv64x60_handle *bh, + struct mv64x60_setup_info *si); + +static u32 mv64360_translate_size(u32 base, u32 size, u32 num_bits); +static u32 mv64360_untranslate_size(u32 base, u32 size, u32 num_bits); +static void mv64360_set_pci2mem_window(struct pci_controller *hose, u32 bus, u32 window, u32 base); -static u32 mv64360_is_enabled_32bit(mv64x60_handle_t *bh, u32 window); -static void mv64360_enable_window_32bit(mv64x60_handle_t *bh, u32 window); -static void mv64360_disable_window_32bit(mv64x60_handle_t *bh, u32 window); -static void mv64360_enable_window_64bit(mv64x60_handle_t *bh, u32 window); -static void mv64360_disable_window_64bit(mv64x60_handle_t *bh, u32 window); -static void mv64360_disable_all_windows(mv64x60_handle_t *bh, - mv64x60_setup_info_t *si); -static void mv64360_chip_specific_init(mv64x60_handle_t *bh, - mv64x60_setup_info_t *si); -static void mv64460_chip_specific_init(mv64x60_handle_t *bh, - mv64x60_setup_info_t *si); - - -u8 mv64x60_pci_exclude_bridge = TRUE; - -spinlock_t mv64x60_lock = SPIN_LOCK_UNLOCKED; -spinlock_t mv64x60_rmw_lock = SPIN_LOCK_UNLOCKED; - -static mv64x60_32bit_window_t gt64260_32bit_windows[] __initdata = { - /* CPU->MEM Windows */ - [MV64x60_CPU2MEM_0_WIN] = { - .base_reg = MV64x60_CPU2MEM_0_BASE, - .size_reg = MV64x60_CPU2MEM_0_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2MEM_1_WIN] = { - .base_reg = MV64x60_CPU2MEM_1_BASE, - .size_reg = MV64x60_CPU2MEM_1_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2MEM_2_WIN] = { - .base_reg = MV64x60_CPU2MEM_2_BASE, - .size_reg = MV64x60_CPU2MEM_2_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2MEM_3_WIN] = { - .base_reg = MV64x60_CPU2MEM_3_BASE, - .size_reg = MV64x60_CPU2MEM_3_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* CPU->Device Windows */ - [MV64x60_CPU2DEV_0_WIN] = { - .base_reg = MV64x60_CPU2DEV_0_BASE, - .size_reg = MV64x60_CPU2DEV_0_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2DEV_1_WIN] = { - .base_reg = MV64x60_CPU2DEV_1_BASE, - .size_reg = MV64x60_CPU2DEV_1_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2DEV_2_WIN] = { - .base_reg = MV64x60_CPU2DEV_2_BASE, - .size_reg = MV64x60_CPU2DEV_2_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2DEV_3_WIN] = { - .base_reg = MV64x60_CPU2DEV_3_BASE, - .size_reg = MV64x60_CPU2DEV_3_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* CPU->Boot Window */ - [MV64x60_CPU2BOOT_WIN] = { - .base_reg = MV64x60_CPU2BOOT_0_BASE, - .size_reg = MV64x60_CPU2BOOT_0_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* CPU->PCI 0 Windows */ - [MV64x60_CPU2PCI0_IO_WIN] = { - .base_reg = MV64x60_CPU2PCI0_IO_BASE, - .size_reg = MV64x60_CPU2PCI0_IO_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI0_MEM_0_WIN] = { - .base_reg = MV64x60_CPU2PCI0_MEM_0_BASE, - .size_reg = MV64x60_CPU2PCI0_MEM_0_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI0_MEM_1_WIN] = { - .base_reg = MV64x60_CPU2PCI0_MEM_1_BASE, - .size_reg = MV64x60_CPU2PCI0_MEM_1_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI0_MEM_2_WIN] = { - .base_reg = MV64x60_CPU2PCI0_MEM_2_BASE, - .size_reg = MV64x60_CPU2PCI0_MEM_2_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI0_MEM_3_WIN] = { - .base_reg = MV64x60_CPU2PCI0_MEM_3_BASE, - .size_reg = MV64x60_CPU2PCI0_MEM_3_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* CPU->PCI 1 Windows */ - [MV64x60_CPU2PCI1_IO_WIN] = { - .base_reg = MV64x60_CPU2PCI1_IO_BASE, - .size_reg = MV64x60_CPU2PCI1_IO_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI1_MEM_0_WIN] = { - .base_reg = MV64x60_CPU2PCI1_MEM_0_BASE, - .size_reg = MV64x60_CPU2PCI1_MEM_0_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI1_MEM_1_WIN] = { - .base_reg = MV64x60_CPU2PCI1_MEM_1_BASE, - .size_reg = MV64x60_CPU2PCI1_MEM_1_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI1_MEM_2_WIN] = { - .base_reg = MV64x60_CPU2PCI1_MEM_2_BASE, - .size_reg = MV64x60_CPU2PCI1_MEM_2_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI1_MEM_3_WIN] = { - .base_reg = MV64x60_CPU2PCI1_MEM_3_BASE, - .size_reg = MV64x60_CPU2PCI1_MEM_3_SIZE, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* CPU->SRAM Window (64260 has no integrated SRAM) */ - /* CPU->PCI 0 Remap I/O Window */ - [MV64x60_CPU2PCI0_IO_REMAP_WIN] = { - .base_reg = MV64x60_CPU2PCI0_IO_REMAP, - .size_reg = 0, - .base_bits = 12, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* CPU->PCI 1 Remap I/O Window */ - [MV64x60_CPU2PCI1_IO_REMAP_WIN] = { - .base_reg = MV64x60_CPU2PCI1_IO_REMAP, - .size_reg = 0, - .base_bits = 12, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* CPU Memory Protection Windows */ - [MV64x60_CPU_PROT_0_WIN] = { - .base_reg = MV64x60_CPU_PROT_BASE_0, - .size_reg = MV64x60_CPU_PROT_SIZE_0, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU_PROT_1_WIN] = { - .base_reg = MV64x60_CPU_PROT_BASE_1, - .size_reg = MV64x60_CPU_PROT_SIZE_1, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU_PROT_2_WIN] = { - .base_reg = MV64x60_CPU_PROT_BASE_2, - .size_reg = MV64x60_CPU_PROT_SIZE_2, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU_PROT_3_WIN] = { - .base_reg = MV64x60_CPU_PROT_BASE_3, - .size_reg = MV64x60_CPU_PROT_SIZE_3, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* CPU Snoop Windows */ - [MV64x60_CPU_SNOOP_0_WIN] = { - .base_reg = GT64260_CPU_SNOOP_BASE_0, - .size_reg = GT64260_CPU_SNOOP_SIZE_0, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU_SNOOP_1_WIN] = { - .base_reg = GT64260_CPU_SNOOP_BASE_1, - .size_reg = GT64260_CPU_SNOOP_SIZE_1, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU_SNOOP_2_WIN] = { - .base_reg = GT64260_CPU_SNOOP_BASE_2, - .size_reg = GT64260_CPU_SNOOP_SIZE_2, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU_SNOOP_3_WIN] = { - .base_reg = GT64260_CPU_SNOOP_BASE_3, - .size_reg = GT64260_CPU_SNOOP_SIZE_3, - .base_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* PCI 0->System Memory Remap Windows */ - [MV64x60_PCI02MEM_REMAP_0_WIN] = { - .base_reg = MV64x60_PCI0_SLAVE_MEM_0_REMAP, - .size_reg = 0, - .base_bits = 20, - .size_bits = 0, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0 }, - [MV64x60_PCI02MEM_REMAP_1_WIN] = { - .base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP, - .size_reg = 0, - .base_bits = 20, - .size_bits = 0, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0 }, - [MV64x60_PCI02MEM_REMAP_2_WIN] = { - .base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP, - .size_reg = 0, - .base_bits = 20, - .size_bits = 0, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0 }, - [MV64x60_PCI02MEM_REMAP_3_WIN] = { - .base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP, - .size_reg = 0, - .base_bits = 20, - .size_bits = 0, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0 }, - /* PCI 1->System Memory Remap Windows */ - [MV64x60_PCI12MEM_REMAP_0_WIN] = { - .base_reg = MV64x60_PCI1_SLAVE_MEM_0_REMAP, - .size_reg = 0, - .base_bits = 20, - .size_bits = 0, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0 }, - [MV64x60_PCI12MEM_REMAP_1_WIN] = { - .base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP, - .size_reg = 0, - .base_bits = 20, - .size_bits = 0, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0 }, - [MV64x60_PCI12MEM_REMAP_2_WIN] = { - .base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP, - .size_reg = 0, - .base_bits = 20, - .size_bits = 0, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0 }, - [MV64x60_PCI12MEM_REMAP_3_WIN] = { - .base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP, - .size_reg = 0, - .base_bits = 20, - .size_bits = 0, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0 }, -}; +static void mv64360_set_pci2regs_window(struct mv64x60_handle *bh, + struct pci_controller *hose, u32 bus, u32 base); +static u32 mv64360_is_enabled_32bit(struct mv64x60_handle *bh, u32 window); +static void mv64360_enable_window_32bit(struct mv64x60_handle *bh, u32 window); +static void mv64360_disable_window_32bit(struct mv64x60_handle *bh, u32 window); +static void mv64360_enable_window_64bit(struct mv64x60_handle *bh, u32 window); +static void mv64360_disable_window_64bit(struct mv64x60_handle *bh, u32 window); +static void mv64360_disable_all_windows(struct mv64x60_handle *bh, + struct mv64x60_setup_info *si); +static void mv64360_config_io2mem_windows(struct mv64x60_handle *bh, + struct mv64x60_setup_info *si, + u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]); +static void mv64360_set_mpsc2regs_window(struct mv64x60_handle *bh, u32 base); +static void mv64360_chip_specific_init(struct mv64x60_handle *bh, + struct mv64x60_setup_info *si); +static void mv64460_chip_specific_init(struct mv64x60_handle *bh, + struct mv64x60_setup_info *si); -static mv64x60_64bit_window_t gt64260_64bit_windows[] __initdata = { - /* CPU->PCI 0 MEM Remap Windows */ - [MV64x60_CPU2PCI0_MEM_0_REMAP_WIN] = { - .base_hi_reg = MV64x60_CPU2PCI0_MEM_0_REMAP_HI, - .base_lo_reg = MV64x60_CPU2PCI0_MEM_0_REMAP_LO, - .size_reg = 0, - .base_lo_bits = 12, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI0_MEM_1_REMAP_WIN] = { - .base_hi_reg = MV64x60_CPU2PCI0_MEM_1_REMAP_HI, - .base_lo_reg = MV64x60_CPU2PCI0_MEM_1_REMAP_LO, - .size_reg = 0, - .base_lo_bits = 12, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI0_MEM_2_REMAP_WIN] = { - .base_hi_reg = MV64x60_CPU2PCI0_MEM_2_REMAP_HI, - .base_lo_reg = MV64x60_CPU2PCI0_MEM_2_REMAP_LO, - .size_reg = 0, - .base_lo_bits = 12, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI0_MEM_3_REMAP_WIN] = { - .base_hi_reg = MV64x60_CPU2PCI0_MEM_3_REMAP_HI, - .base_lo_reg = MV64x60_CPU2PCI0_MEM_3_REMAP_LO, - .size_reg = 0, - .base_lo_bits = 12, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* CPU->PCI 1 MEM Remap Windows */ - [MV64x60_CPU2PCI1_MEM_0_REMAP_WIN] = { - .base_hi_reg = MV64x60_CPU2PCI1_MEM_0_REMAP_HI, - .base_lo_reg = MV64x60_CPU2PCI1_MEM_0_REMAP_LO, - .size_reg = 0, - .base_lo_bits = 12, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI1_MEM_1_REMAP_WIN] = { - .base_hi_reg = MV64x60_CPU2PCI1_MEM_1_REMAP_HI, - .base_lo_reg = MV64x60_CPU2PCI1_MEM_1_REMAP_LO, - .size_reg = 0, - .base_lo_bits = 12, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI1_MEM_2_REMAP_WIN] = { - .base_hi_reg = MV64x60_CPU2PCI1_MEM_2_REMAP_HI, - .base_lo_reg = MV64x60_CPU2PCI1_MEM_2_REMAP_LO, - .size_reg = 0, - .base_lo_bits = 12, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI1_MEM_3_REMAP_WIN] = { - .base_hi_reg = MV64x60_CPU2PCI1_MEM_3_REMAP_HI, - .base_lo_reg = MV64x60_CPU2PCI1_MEM_3_REMAP_LO, - .size_reg = 0, - .base_lo_bits = 12, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* PCI 0->MEM Access Control Windows */ - [MV64x60_PCI02MEM_ACC_CNTL_0_WIN] = { - .base_hi_reg = MV64x60_PCI0_ACC_CNTL_0_BASE_HI, - .base_lo_reg = MV64x60_PCI0_ACC_CNTL_0_BASE_LO, - .size_reg = MV64x60_PCI0_ACC_CNTL_0_SIZE, - .base_lo_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_PCI02MEM_ACC_CNTL_1_WIN] = { - .base_hi_reg = MV64x60_PCI0_ACC_CNTL_1_BASE_HI, - .base_lo_reg = MV64x60_PCI0_ACC_CNTL_1_BASE_LO, - .size_reg = MV64x60_PCI0_ACC_CNTL_1_SIZE, - .base_lo_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_PCI02MEM_ACC_CNTL_2_WIN] = { - .base_hi_reg = MV64x60_PCI0_ACC_CNTL_2_BASE_HI, - .base_lo_reg = MV64x60_PCI0_ACC_CNTL_2_BASE_LO, - .size_reg = MV64x60_PCI0_ACC_CNTL_2_SIZE, - .base_lo_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_PCI02MEM_ACC_CNTL_3_WIN] = { - .base_hi_reg = MV64x60_PCI0_ACC_CNTL_3_BASE_HI, - .base_lo_reg = MV64x60_PCI0_ACC_CNTL_3_BASE_LO, - .size_reg = MV64x60_PCI0_ACC_CNTL_3_SIZE, - .base_lo_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* PCI 1->MEM Access Control Windows */ - [MV64x60_PCI12MEM_ACC_CNTL_0_WIN] = { - .base_hi_reg = MV64x60_PCI1_ACC_CNTL_0_BASE_HI, - .base_lo_reg = MV64x60_PCI1_ACC_CNTL_0_BASE_LO, - .size_reg = MV64x60_PCI1_ACC_CNTL_0_SIZE, - .base_lo_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_PCI12MEM_ACC_CNTL_1_WIN] = { - .base_hi_reg = MV64x60_PCI1_ACC_CNTL_1_BASE_HI, - .base_lo_reg = MV64x60_PCI1_ACC_CNTL_1_BASE_LO, - .size_reg = MV64x60_PCI1_ACC_CNTL_1_SIZE, - .base_lo_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_PCI12MEM_ACC_CNTL_2_WIN] = { - .base_hi_reg = MV64x60_PCI1_ACC_CNTL_2_BASE_HI, - .base_lo_reg = MV64x60_PCI1_ACC_CNTL_2_BASE_LO, - .size_reg = MV64x60_PCI1_ACC_CNTL_2_SIZE, - .base_lo_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_PCI12MEM_ACC_CNTL_3_WIN] = { - .base_hi_reg = MV64x60_PCI1_ACC_CNTL_3_BASE_HI, - .base_lo_reg = MV64x60_PCI1_ACC_CNTL_3_BASE_LO, - .size_reg = MV64x60_PCI1_ACC_CNTL_3_SIZE, - .base_lo_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* PCI 0->MEM Snoop Windows */ - [MV64x60_PCI02MEM_SNOOP_0_WIN] = { - .base_hi_reg = GT64260_PCI0_SNOOP_0_BASE_HI, - .base_lo_reg = GT64260_PCI0_SNOOP_0_BASE_LO, - .size_reg = GT64260_PCI0_SNOOP_0_SIZE, - .base_lo_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_PCI02MEM_SNOOP_1_WIN] = { - .base_hi_reg = GT64260_PCI0_SNOOP_1_BASE_HI, - .base_lo_reg = GT64260_PCI0_SNOOP_1_BASE_LO, - .size_reg = GT64260_PCI0_SNOOP_1_SIZE, - .base_lo_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_PCI02MEM_SNOOP_2_WIN] = { - .base_hi_reg = GT64260_PCI0_SNOOP_2_BASE_HI, - .base_lo_reg = GT64260_PCI0_SNOOP_2_BASE_LO, - .size_reg = GT64260_PCI0_SNOOP_2_SIZE, - .base_lo_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_PCI02MEM_SNOOP_3_WIN] = { - .base_hi_reg = GT64260_PCI0_SNOOP_3_BASE_HI, - .base_lo_reg = GT64260_PCI0_SNOOP_3_BASE_LO, - .size_reg = GT64260_PCI0_SNOOP_3_SIZE, - .base_lo_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* PCI 1->MEM Snoop Windows */ - [MV64x60_PCI12MEM_SNOOP_0_WIN] = { - .base_hi_reg = GT64260_PCI1_SNOOP_0_BASE_HI, - .base_lo_reg = GT64260_PCI1_SNOOP_0_BASE_LO, - .size_reg = GT64260_PCI1_SNOOP_0_SIZE, - .base_lo_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_PCI12MEM_SNOOP_1_WIN] = { - .base_hi_reg = GT64260_PCI1_SNOOP_1_BASE_HI, - .base_lo_reg = GT64260_PCI1_SNOOP_1_BASE_LO, - .size_reg = GT64260_PCI1_SNOOP_1_SIZE, - .base_lo_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_PCI12MEM_SNOOP_2_WIN] = { - .base_hi_reg = GT64260_PCI1_SNOOP_2_BASE_HI, - .base_lo_reg = GT64260_PCI1_SNOOP_2_BASE_LO, - .size_reg = GT64260_PCI1_SNOOP_2_SIZE, - .base_lo_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_PCI12MEM_SNOOP_3_WIN] = { - .base_hi_reg = GT64260_PCI1_SNOOP_3_BASE_HI, - .base_lo_reg = GT64260_PCI1_SNOOP_3_BASE_LO, - .size_reg = GT64260_PCI1_SNOOP_3_SIZE, - .base_lo_bits = 12, - .size_bits = 12, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, -}; -static mv64x60_chip_info_t gt64260a_ci __initdata = { +/* + * Define tables that have the chip-specific info for each type of + * Marvell bridge chip. + */ +static struct mv64x60_chip_info gt64260a_ci __initdata = { /* GT64260A */ .translate_size = gt64260_translate_size, .untranslate_size = gt64260_untranslate_size, .set_pci2mem_window = gt64260_set_pci2mem_window, + .set_pci2regs_window = gt64260_set_pci2regs_window, .is_enabled_32bit = gt64260_is_enabled_32bit, .enable_window_32bit = gt64260_enable_window_32bit, .disable_window_32bit = gt64260_disable_window_32bit, @@ -657,10 +100,11 @@ static mv64x60_chip_info_t gt64260a_ci __initdata = { .window_tab_64bit = gt64260_64bit_windows, }; -static mv64x60_chip_info_t gt64260b_ci __initdata = { +static struct mv64x60_chip_info gt64260b_ci __initdata = { /* GT64260B */ .translate_size = gt64260_translate_size, .untranslate_size = gt64260_untranslate_size, .set_pci2mem_window = gt64260_set_pci2mem_window, + .set_pci2regs_window = gt64260_set_pci2regs_window, .is_enabled_32bit = gt64260_is_enabled_32bit, .enable_window_32bit = gt64260_enable_window_32bit, .disable_window_32bit = gt64260_disable_window_32bit, @@ -672,478 +116,345 @@ static mv64x60_chip_info_t gt64260b_ci __initdata = { .window_tab_64bit = gt64260_64bit_windows, }; - -static mv64x60_32bit_window_t mv64360_32bit_windows[] __initdata = { - /* CPU->MEM Windows */ - [MV64x60_CPU2MEM_0_WIN] = { - .base_reg = MV64x60_CPU2MEM_0_BASE, - .size_reg = MV64x60_CPU2MEM_0_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2MEM_1_WIN] = { - .base_reg = MV64x60_CPU2MEM_1_BASE, - .size_reg = MV64x60_CPU2MEM_1_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 1 }, - [MV64x60_CPU2MEM_2_WIN] = { - .base_reg = MV64x60_CPU2MEM_2_BASE, - .size_reg = MV64x60_CPU2MEM_2_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 2 }, - [MV64x60_CPU2MEM_3_WIN] = { - .base_reg = MV64x60_CPU2MEM_3_BASE, - .size_reg = MV64x60_CPU2MEM_3_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 3 }, - /* CPU->Device Windows */ - [MV64x60_CPU2DEV_0_WIN] = { - .base_reg = MV64x60_CPU2DEV_0_BASE, - .size_reg = MV64x60_CPU2DEV_0_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 4 }, - [MV64x60_CPU2DEV_1_WIN] = { - .base_reg = MV64x60_CPU2DEV_1_BASE, - .size_reg = MV64x60_CPU2DEV_1_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 5 }, - [MV64x60_CPU2DEV_2_WIN] = { - .base_reg = MV64x60_CPU2DEV_2_BASE, - .size_reg = MV64x60_CPU2DEV_2_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 6 }, - [MV64x60_CPU2DEV_3_WIN] = { - .base_reg = MV64x60_CPU2DEV_3_BASE, - .size_reg = MV64x60_CPU2DEV_3_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 7 }, - /* CPU->Boot Window */ - [MV64x60_CPU2BOOT_WIN] = { - .base_reg = MV64x60_CPU2BOOT_0_BASE, - .size_reg = MV64x60_CPU2BOOT_0_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 8 }, - /* CPU->PCI 0 Windows */ - [MV64x60_CPU2PCI0_IO_WIN] = { - .base_reg = MV64x60_CPU2PCI0_IO_BASE, - .size_reg = MV64x60_CPU2PCI0_IO_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 9 }, - [MV64x60_CPU2PCI0_MEM_0_WIN] = { - .base_reg = MV64x60_CPU2PCI0_MEM_0_BASE, - .size_reg = MV64x60_CPU2PCI0_MEM_0_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 10 }, - [MV64x60_CPU2PCI0_MEM_1_WIN] = { - .base_reg = MV64x60_CPU2PCI0_MEM_1_BASE, - .size_reg = MV64x60_CPU2PCI0_MEM_1_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 11 }, - [MV64x60_CPU2PCI0_MEM_2_WIN] = { - .base_reg = MV64x60_CPU2PCI0_MEM_2_BASE, - .size_reg = MV64x60_CPU2PCI0_MEM_2_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 12 }, - [MV64x60_CPU2PCI0_MEM_3_WIN] = { - .base_reg = MV64x60_CPU2PCI0_MEM_3_BASE, - .size_reg = MV64x60_CPU2PCI0_MEM_3_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 13 }, - /* CPU->PCI 1 Windows */ - [MV64x60_CPU2PCI1_IO_WIN] = { - .base_reg = MV64x60_CPU2PCI1_IO_BASE, - .size_reg = MV64x60_CPU2PCI1_IO_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 14 }, - [MV64x60_CPU2PCI1_MEM_0_WIN] = { - .base_reg = MV64x60_CPU2PCI1_MEM_0_BASE, - .size_reg = MV64x60_CPU2PCI1_MEM_0_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 15 }, - [MV64x60_CPU2PCI1_MEM_1_WIN] = { - .base_reg = MV64x60_CPU2PCI1_MEM_1_BASE, - .size_reg = MV64x60_CPU2PCI1_MEM_1_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 16 }, - [MV64x60_CPU2PCI1_MEM_2_WIN] = { - .base_reg = MV64x60_CPU2PCI1_MEM_2_BASE, - .size_reg = MV64x60_CPU2PCI1_MEM_2_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 17 }, - [MV64x60_CPU2PCI1_MEM_3_WIN] = { - .base_reg = MV64x60_CPU2PCI1_MEM_3_BASE, - .size_reg = MV64x60_CPU2PCI1_MEM_3_SIZE, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 18 }, - /* CPU->SRAM Window */ - [MV64x60_CPU2SRAM_WIN] = { - .base_reg = MV64360_CPU2SRAM_BASE, - .size_reg = 0, - .base_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 19 }, - /* CPU->PCI 0 Remap I/O Window */ - [MV64x60_CPU2PCI0_IO_REMAP_WIN] = { - .base_reg = MV64x60_CPU2PCI0_IO_REMAP, - .size_reg = 0, - .base_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* CPU->PCI 1 Remap I/O Window */ - [MV64x60_CPU2PCI1_IO_REMAP_WIN] = { - .base_reg = MV64x60_CPU2PCI1_IO_REMAP, - .size_reg = 0, - .base_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* CPU Memory Protection Windows */ - [MV64x60_CPU_PROT_0_WIN] = { - .base_reg = MV64x60_CPU_PROT_BASE_0, - .size_reg = MV64x60_CPU_PROT_SIZE_0, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0x80000000 | 31 }, - [MV64x60_CPU_PROT_1_WIN] = { - .base_reg = MV64x60_CPU_PROT_BASE_1, - .size_reg = MV64x60_CPU_PROT_SIZE_1, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0x80000000 | 31 }, - [MV64x60_CPU_PROT_2_WIN] = { - .base_reg = MV64x60_CPU_PROT_BASE_2, - .size_reg = MV64x60_CPU_PROT_SIZE_2, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0x80000000 | 31 }, - [MV64x60_CPU_PROT_3_WIN] = { - .base_reg = MV64x60_CPU_PROT_BASE_3, - .size_reg = MV64x60_CPU_PROT_SIZE_3, - .base_bits = 16, - .size_bits = 16, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0x80000000 | 31 }, - /* CPU Snoop Windows -- don't exist on 64360 */ - /* PCI 0->System Memory Remap Windows */ - [MV64x60_PCI02MEM_REMAP_0_WIN] = { - .base_reg = MV64x60_PCI0_SLAVE_MEM_0_REMAP, - .size_reg = 0, - .base_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0 }, - [MV64x60_PCI02MEM_REMAP_1_WIN] = { - .base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP, - .size_reg = 0, - .base_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0 }, - [MV64x60_PCI02MEM_REMAP_2_WIN] = { - .base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP, - .size_reg = 0, - .base_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0 }, - [MV64x60_PCI02MEM_REMAP_3_WIN] = { - .base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP, - .size_reg = 0, - .base_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0 }, - /* PCI 1->System Memory Remap Windows */ - [MV64x60_PCI12MEM_REMAP_0_WIN] = { - .base_reg = MV64x60_PCI1_SLAVE_MEM_0_REMAP, - .size_reg = 0, - .base_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0 }, - [MV64x60_PCI12MEM_REMAP_1_WIN] = { - .base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP, - .size_reg = 0, - .base_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0 }, - [MV64x60_PCI12MEM_REMAP_2_WIN] = { - .base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP, - .size_reg = 0, - .base_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0 }, - [MV64x60_PCI12MEM_REMAP_3_WIN] = { - .base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP, - .size_reg = 0, - .base_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0 }, -}; - -static mv64x60_64bit_window_t mv64360_64bit_windows[MV64x60_64BIT_WIN_COUNT] - __initdata = { - /* CPU->PCI 0 MEM Remap Windows */ - [MV64x60_CPU2PCI0_MEM_0_REMAP_WIN] = { - .base_hi_reg = MV64x60_CPU2PCI0_MEM_0_REMAP_HI, - .base_lo_reg = MV64x60_CPU2PCI0_MEM_0_REMAP_LO, - .size_reg = 0, - .base_lo_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI0_MEM_1_REMAP_WIN] = { - .base_hi_reg = MV64x60_CPU2PCI0_MEM_1_REMAP_HI, - .base_lo_reg = MV64x60_CPU2PCI0_MEM_1_REMAP_LO, - .size_reg = 0, - .base_lo_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI0_MEM_2_REMAP_WIN] = { - .base_hi_reg = MV64x60_CPU2PCI0_MEM_2_REMAP_HI, - .base_lo_reg = MV64x60_CPU2PCI0_MEM_2_REMAP_LO, - .size_reg = 0, - .base_lo_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI0_MEM_3_REMAP_WIN] = { - .base_hi_reg = MV64x60_CPU2PCI0_MEM_3_REMAP_HI, - .base_lo_reg = MV64x60_CPU2PCI0_MEM_3_REMAP_LO, - .size_reg = 0, - .base_lo_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* CPU->PCI 1 MEM Remap Windows */ - [MV64x60_CPU2PCI1_MEM_0_REMAP_WIN] = { - .base_hi_reg = MV64x60_CPU2PCI1_MEM_0_REMAP_HI, - .base_lo_reg = MV64x60_CPU2PCI1_MEM_0_REMAP_LO, - .size_reg = 0, - .base_lo_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI1_MEM_1_REMAP_WIN] = { - .base_hi_reg = MV64x60_CPU2PCI1_MEM_1_REMAP_HI, - .base_lo_reg = MV64x60_CPU2PCI1_MEM_1_REMAP_LO, - .size_reg = 0, - .base_lo_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI1_MEM_2_REMAP_WIN] = { - .base_hi_reg = MV64x60_CPU2PCI1_MEM_2_REMAP_HI, - .base_lo_reg = MV64x60_CPU2PCI1_MEM_2_REMAP_LO, - .size_reg = 0, - .base_lo_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - [MV64x60_CPU2PCI1_MEM_3_REMAP_WIN] = { - .base_hi_reg = MV64x60_CPU2PCI1_MEM_3_REMAP_HI, - .base_lo_reg = MV64x60_CPU2PCI1_MEM_3_REMAP_LO, - .size_reg = 0, - .base_lo_bits = 16, - .size_bits = 0, - .get_from_field = mv64x60_shift_left, - .map_to_field = mv64x60_shift_right, - .extra = 0 }, - /* PCI 0->MEM Access Control Windows */ - [MV64x60_PCI02MEM_ACC_CNTL_0_WIN] = { - .base_hi_reg = MV64x60_PCI0_ACC_CNTL_0_BASE_HI, - .base_lo_reg = MV64x60_PCI0_ACC_CNTL_0_BASE_LO, - .size_reg = MV64x60_PCI0_ACC_CNTL_0_SIZE, - .base_lo_bits = 20, - .size_bits = 20, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0x80000000 | 0 }, - [MV64x60_PCI02MEM_ACC_CNTL_1_WIN] = { - .base_hi_reg = MV64x60_PCI0_ACC_CNTL_1_BASE_HI, - .base_lo_reg = MV64x60_PCI0_ACC_CNTL_1_BASE_LO, - .size_reg = MV64x60_PCI0_ACC_CNTL_1_SIZE, - .base_lo_bits = 20, - .size_bits = 20, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0x80000000 | 0 }, - [MV64x60_PCI02MEM_ACC_CNTL_2_WIN] = { - .base_hi_reg = MV64x60_PCI0_ACC_CNTL_2_BASE_HI, - .base_lo_reg = MV64x60_PCI0_ACC_CNTL_2_BASE_LO, - .size_reg = MV64x60_PCI0_ACC_CNTL_2_SIZE, - .base_lo_bits = 20, - .size_bits = 20, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0x80000000 | 0 }, - [MV64x60_PCI02MEM_ACC_CNTL_3_WIN] = { - .base_hi_reg = MV64x60_PCI0_ACC_CNTL_3_BASE_HI, - .base_lo_reg = MV64x60_PCI0_ACC_CNTL_3_BASE_LO, - .size_reg = MV64x60_PCI0_ACC_CNTL_3_SIZE, - .base_lo_bits = 20, - .size_bits = 20, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0x80000000 | 0 }, - /* PCI 1->MEM Access Control Windows */ - [MV64x60_PCI12MEM_ACC_CNTL_0_WIN] = { - .base_hi_reg = MV64x60_PCI1_ACC_CNTL_0_BASE_HI, - .base_lo_reg = MV64x60_PCI1_ACC_CNTL_0_BASE_LO, - .size_reg = MV64x60_PCI1_ACC_CNTL_0_SIZE, - .base_lo_bits = 20, - .size_bits = 20, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0x80000000 | 0 }, - [MV64x60_PCI12MEM_ACC_CNTL_1_WIN] = { - .base_hi_reg = MV64x60_PCI1_ACC_CNTL_1_BASE_HI, - .base_lo_reg = MV64x60_PCI1_ACC_CNTL_1_BASE_LO, - .size_reg = MV64x60_PCI1_ACC_CNTL_1_SIZE, - .base_lo_bits = 20, - .size_bits = 20, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0x80000000 | 0 }, - [MV64x60_PCI12MEM_ACC_CNTL_2_WIN] = { - .base_hi_reg = MV64x60_PCI1_ACC_CNTL_2_BASE_HI, - .base_lo_reg = MV64x60_PCI1_ACC_CNTL_2_BASE_LO, - .size_reg = MV64x60_PCI1_ACC_CNTL_2_SIZE, - .base_lo_bits = 20, - .size_bits = 20, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0x80000000 | 0 }, - [MV64x60_PCI12MEM_ACC_CNTL_3_WIN] = { - .base_hi_reg = MV64x60_PCI1_ACC_CNTL_3_BASE_HI, - .base_lo_reg = MV64x60_PCI1_ACC_CNTL_3_BASE_LO, - .size_reg = MV64x60_PCI1_ACC_CNTL_3_SIZE, - .base_lo_bits = 20, - .size_bits = 20, - .get_from_field = mv64x60_mask, - .map_to_field = mv64x60_mask, - .extra = 0x80000000 | 0 }, - /* PCI 0->MEM Snoop Windows -- don't exist on 64360 */ - /* PCI 1->MEM Snoop Windows -- don't exist on 64360 */ -}; - -static mv64x60_chip_info_t mv64360_ci __initdata = { +static struct mv64x60_chip_info mv64360_ci __initdata = { /* MV64360 */ .translate_size = mv64360_translate_size, .untranslate_size = mv64360_untranslate_size, .set_pci2mem_window = mv64360_set_pci2mem_window, + .set_pci2regs_window = mv64360_set_pci2regs_window, .is_enabled_32bit = mv64360_is_enabled_32bit, .enable_window_32bit = mv64360_enable_window_32bit, .disable_window_32bit = mv64360_disable_window_32bit, .enable_window_64bit = mv64360_enable_window_64bit, .disable_window_64bit = mv64360_disable_window_64bit, .disable_all_windows = mv64360_disable_all_windows, + .config_io2mem_windows = mv64360_config_io2mem_windows, + .set_mpsc2regs_window = mv64360_set_mpsc2regs_window, .chip_specific_init = mv64360_chip_specific_init, .window_tab_32bit = mv64360_32bit_windows, .window_tab_64bit = mv64360_64bit_windows, }; -static mv64x60_chip_info_t mv64460_ci __initdata = { +static struct mv64x60_chip_info mv64460_ci __initdata = { /* MV64460 */ .translate_size = mv64360_translate_size, .untranslate_size = mv64360_untranslate_size, .set_pci2mem_window = mv64360_set_pci2mem_window, + .set_pci2regs_window = mv64360_set_pci2regs_window, .is_enabled_32bit = mv64360_is_enabled_32bit, .enable_window_32bit = mv64360_enable_window_32bit, .disable_window_32bit = mv64360_disable_window_32bit, .enable_window_64bit = mv64360_enable_window_64bit, .disable_window_64bit = mv64360_disable_window_64bit, .disable_all_windows = mv64360_disable_all_windows, + .config_io2mem_windows = mv64360_config_io2mem_windows, + .set_mpsc2regs_window = mv64360_set_mpsc2regs_window, .chip_specific_init = mv64460_chip_specific_init, .window_tab_32bit = mv64360_32bit_windows, .window_tab_64bit = mv64360_64bit_windows, }; +/* + ***************************************************************************** + * + * Platform Device Definitions + * + ***************************************************************************** + */ +#ifdef CONFIG_SERIAL_MPSC +static struct mpsc_shared_pdata mv64x60_mpsc_shared_pdata = { + .mrr_val = 0x3ffffe38, + .rcrr_val = 0, + .tcrr_val = 0, + .intr_cause_val = 0, + .intr_mask_val = 0, +}; + +static struct resource mv64x60_mpsc_shared_resources[] = { + /* Do not change the order of the IORESOURCE_MEM resources */ + [0] = { + .name = "mpsc routing base", + .start = MV64x60_MPSC_ROUTING_OFFSET, + .end = MV64x60_MPSC_ROUTING_OFFSET + + MPSC_ROUTING_REG_BLOCK_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "sdma intr base", + .start = MV64x60_SDMA_INTR_OFFSET, + .end = MV64x60_SDMA_INTR_OFFSET + + MPSC_SDMA_INTR_REG_BLOCK_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mpsc_shared_device = { /* Shared device */ + .name = MPSC_SHARED_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv64x60_mpsc_shared_resources), + .resource = mv64x60_mpsc_shared_resources, + .dev = { + .platform_data = &mv64x60_mpsc_shared_pdata, + }, +}; + +static struct mpsc_pdata mv64x60_mpsc0_pdata = { + .mirror_regs = 0, + .cache_mgmt = 0, + .max_idle = 0, + .default_baud = 9600, + .default_bits = 8, + .default_parity = 'n', + .default_flow = 'n', + .chr_1_val = 0x00000000, + .chr_2_val = 0x00000000, + .chr_10_val = 0x00000003, + .mpcr_val = 0, + .bcr_val = 0, + .brg_can_tune = 0, + .brg_clk_src = 8, /* Default to TCLK */ + .brg_clk_freq = 100000000, /* Default to 100 MHz */ +}; + +static struct resource mv64x60_mpsc0_resources[] = { + /* Do not change the order of the IORESOURCE_MEM resources */ + [0] = { + .name = "mpsc 0 base", + .start = MV64x60_MPSC_0_OFFSET, + .end = MV64x60_MPSC_0_OFFSET + MPSC_REG_BLOCK_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "sdma 0 base", + .start = MV64x60_SDMA_0_OFFSET, + .end = MV64x60_SDMA_0_OFFSET + MPSC_SDMA_REG_BLOCK_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .name = "brg 0 base", + .start = MV64x60_BRG_0_OFFSET, + .end = MV64x60_BRG_0_OFFSET + MPSC_BRG_REG_BLOCK_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [3] = { + .name = "sdma 0 irq", + .start = MV64x60_IRQ_SDMA_0, + .end = MV64x60_IRQ_SDMA_0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mpsc0_device = { + .name = MPSC_CTLR_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv64x60_mpsc0_resources), + .resource = mv64x60_mpsc0_resources, + .dev = { + .platform_data = &mv64x60_mpsc0_pdata, + }, +}; + +static struct mpsc_pdata mv64x60_mpsc1_pdata = { + .mirror_regs = 0, + .cache_mgmt = 0, + .max_idle = 0, + .default_baud = 9600, + .default_bits = 8, + .default_parity = 'n', + .default_flow = 'n', + .chr_1_val = 0x00000000, + .chr_1_val = 0x00000000, + .chr_2_val = 0x00000000, + .chr_10_val = 0x00000003, + .mpcr_val = 0, + .bcr_val = 0, + .brg_can_tune = 0, + .brg_clk_src = 8, /* Default to TCLK */ + .brg_clk_freq = 100000000, /* Default to 100 MHz */ +}; + +static struct resource mv64x60_mpsc1_resources[] = { + /* Do not change the order of the IORESOURCE_MEM resources */ + [0] = { + .name = "mpsc 1 base", + .start = MV64x60_MPSC_1_OFFSET, + .end = MV64x60_MPSC_1_OFFSET + MPSC_REG_BLOCK_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "sdma 1 base", + .start = MV64x60_SDMA_1_OFFSET, + .end = MV64x60_SDMA_1_OFFSET + MPSC_SDMA_REG_BLOCK_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .name = "brg 1 base", + .start = MV64x60_BRG_1_OFFSET, + .end = MV64x60_BRG_1_OFFSET + MPSC_BRG_REG_BLOCK_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [3] = { + .name = "sdma 1 irq", + .start = MV64360_IRQ_SDMA_1, + .end = MV64360_IRQ_SDMA_1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mpsc1_device = { + .name = MPSC_CTLR_NAME, + .id = 1, + .num_resources = ARRAY_SIZE(mv64x60_mpsc1_resources), + .resource = mv64x60_mpsc1_resources, + .dev = { + .platform_data = &mv64x60_mpsc1_pdata, + }, +}; +#endif + +#ifdef CONFIG_MV643XX_ETH +static struct resource mv64x60_eth_shared_resources[] = { + [0] = { + .name = "ethernet shared base", + .start = MV64340_ETH_SHARED_REGS, + .end = MV64340_ETH_SHARED_REGS + + MV64340_ETH_SHARED_REGS_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mv64x60_eth_shared_device = { + .name = MV64XXX_ETH_SHARED_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv64x60_eth_shared_resources), + .resource = mv64x60_eth_shared_resources, +}; + +#ifdef CONFIG_MV643XX_ETH_0 +static struct resource mv64x60_eth0_resources[] = { + [0] = { + .name = "eth0 irq", + .start = MV64x60_IRQ_ETH_0, + .end = MV64x60_IRQ_ETH_0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mv64xxx_eth_platform_data eth0_pd; + +static struct platform_device eth0_device = { + .name = MV64XXX_ETH_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv64x60_eth0_resources), + .resource = mv64x60_eth0_resources, + .dev = { + .platform_data = ð0_pd, + }, +}; +#endif + +#ifdef CONFIG_MV643XX_ETH_1 +static struct resource mv64x60_eth1_resources[] = { + [0] = { + .name = "eth1 irq", + .start = MV64x60_IRQ_ETH_1, + .end = MV64x60_IRQ_ETH_1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mv64xxx_eth_platform_data eth1_pd; + +static struct platform_device eth1_device = { + .name = MV64XXX_ETH_NAME, + .id = 1, + .num_resources = ARRAY_SIZE(mv64x60_eth1_resources), + .resource = mv64x60_eth1_resources, + .dev = { + .platform_data = ð1_pd, + }, +}; +#endif + +#ifdef CONFIG_MV643XX_ETH_2 +static struct resource mv64x60_eth2_resources[] = { + [0] = { + .name = "eth2 irq", + .start = MV64x60_IRQ_ETH_2, + .end = MV64x60_IRQ_ETH_2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mv64xxx_eth_platform_data eth2_pd; + +static struct platform_device eth2_device = { + .name = MV64XXX_ETH_NAME, + .id = 2, + .num_resources = ARRAY_SIZE(mv64x60_eth2_resources), + .resource = mv64x60_eth2_resources, + .dev = { + .platform_data = ð2_pd, + }, +}; +#endif +#endif + +#ifdef CONFIG_I2C_MV64XXX +static struct mv64xxx_i2c_pdata mv64xxx_i2c_pdata = { + .freq_m = 8, + .freq_n = 3, + .timeout = 1000, /* Default timeout of 1 second */ + .retries = 1, +}; + +static struct resource mv64xxx_i2c_resources[] = { + /* Do not change the order of the IORESOURCE_MEM resources */ + [0] = { + .name = "mv64xxx i2c base", + .start = MV64XXX_I2C_OFFSET, + .end = MV64XXX_I2C_OFFSET + MV64XXX_I2C_REG_BLOCK_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "mv64xxx i2c irq", + .start = MV64x60_IRQ_I2C, + .end = MV64x60_IRQ_I2C, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device i2c_device = { + .name = MV64XXX_I2C_CTLR_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv64xxx_i2c_resources), + .resource = mv64xxx_i2c_resources, + .dev = { + .platform_data = &mv64xxx_i2c_pdata, + }, +}; +#endif + +static struct platform_device *mv64x60_pd_devs[] __initdata = { +#ifdef CONFIG_SERIAL_MPSC + &mpsc_shared_device, + &mpsc0_device, + &mpsc1_device, +#endif +#ifdef CONFIG_MV643XX_ETH + &mv64x60_eth_shared_device, +#endif +#ifdef CONFIG_MV643XX_ETH_0 + ð0_device, +#endif +#ifdef CONFIG_MV643XX_ETH_1 + ð1_device, +#endif +#ifdef CONFIG_MV643XX_ETH_2 + ð2_device, +#endif +#ifdef CONFIG_I2C_MV64XXX + &i2c_device, +#endif +}; /* ***************************************************************************** @@ -1160,78 +471,134 @@ static mv64x60_chip_info_t mv64460_ci __initdata = { * calls to routines in this file. */ int __init -mv64x60_init(mv64x60_handle_t *bh, mv64x60_setup_info_t *si) +mv64x60_init(struct mv64x60_handle *bh, struct mv64x60_setup_info *si) { u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]; - int rc = 0; if (ppc_md.progress) - ppc_md.progress("mv64x60_init: Enter", 0x0); + ppc_md.progress("mv64x60 initialization", 0x0); + spin_lock_init(&mv64x60_lock); mv64x60_early_init(bh, si); - mv64x60_alloc_hoses(bh, si); /* Allocate pci hose structures */ - if (mv64x60_get_type(bh)) - return -1; - - if (mv64x60_setup_for_chip(bh) != 0) { - iounmap((void *)bh->v_base); + if (mv64x60_get_type(bh) || mv64x60_setup_for_chip(bh)) { + iounmap(bh->v_base); + bh->v_base = 0; if (ppc_md.progress) - ppc_md.progress("mv64x60_init: Exit--error", 0x0); + ppc_md.progress("mv64x60_init: Can't determine chip",0); return -1; } - bh->ci->disable_all_windows(bh, si); /* Disable windows except mem ctlr */ - mv64x60_config_cpu2pci_windows(bh, si); /* Init CPU->PCI windows */ - mv64x60_get_mem_windows(bh, mem_windows); /* Read mem ctlr regs */ - mv64x60_config_cpu2mem_windows(bh, si, mem_windows); /* CPU->MEM setup*/ - mv64x60_config_pci2mem_windows(bh, si, mem_windows); /* PCI->Sys MEM */ - mv64x60_init_hoses(bh, si); /* Init hose structs & PCI params */ - bh->ci->chip_specific_init(bh, si); - mv64x60_enumerate_buses(bh, si); /* Enumerate PCI buses */ - ocp_for_each_device(mv64x60_fixup_ocp, (void *)bh); + bh->ci->disable_all_windows(bh, si); + mv64x60_get_mem_windows(bh, mem_windows); + mv64x60_config_cpu2mem_windows(bh, si, mem_windows); - if (ppc_md.progress) - ppc_md.progress("mv64x60_init: Exit", 0x0); + if (bh->ci->config_io2mem_windows) + bh->ci->config_io2mem_windows(bh, si, mem_windows); + if (bh->ci->set_mpsc2regs_window) + bh->ci->set_mpsc2regs_window(bh, si->phys_reg_base); - return rc; -} /* mv64x60_init() */ + if (si->pci_1.enable_bus) { + bh->io_base_b = (u32)ioremap(si->pci_1.pci_io.cpu_base, + si->pci_1.pci_io.size); + isa_io_base = bh->io_base_b; + } + + if (si->pci_0.enable_bus) { + bh->io_base_a = (u32)ioremap(si->pci_0.pci_io.cpu_base, + si->pci_0.pci_io.size); + isa_io_base = bh->io_base_a; + + mv64x60_alloc_hose(bh, MV64x60_PCI0_CONFIG_ADDR, + MV64x60_PCI0_CONFIG_DATA, &bh->hose_a); + mv64x60_config_resources(bh->hose_a, &si->pci_0, bh->io_base_a); + mv64x60_config_pci_params(bh->hose_a, &si->pci_0); + + mv64x60_config_cpu2pci_windows(bh, &si->pci_0, 0); + mv64x60_config_pci2mem_windows(bh, bh->hose_a, &si->pci_0, 0, + mem_windows); + bh->ci->set_pci2regs_window(bh, bh->hose_a, 0, + si->phys_reg_base); + } + + if (si->pci_1.enable_bus) { + mv64x60_alloc_hose(bh, MV64x60_PCI1_CONFIG_ADDR, + MV64x60_PCI1_CONFIG_DATA, &bh->hose_b); + mv64x60_config_resources(bh->hose_b, &si->pci_1, bh->io_base_b); + mv64x60_config_pci_params(bh->hose_b, &si->pci_1); + + mv64x60_config_cpu2pci_windows(bh, &si->pci_1, 1); + mv64x60_config_pci2mem_windows(bh, bh->hose_b, &si->pci_1, 1, + mem_windows); + bh->ci->set_pci2regs_window(bh, bh->hose_b, 1, + si->phys_reg_base); + } + + bh->ci->chip_specific_init(bh, si); + mv64x60_pd_fixup(bh, mv64x60_pd_devs, ARRAY_SIZE(mv64x60_pd_devs)); + + return 0; +} /* - ***************************************************************************** - * - * Pre-Bridge-Init Routines (Externally Visible) - * - ***************************************************************************** - */ -/* - * mv64x60_get_mem_size() + * mv64x60_early_init() * - * Calculate the amount of memory that the memory controller is set up for. - * This should only be used by board-specific code if there is no other - * way to determine the amount of memory in the system. + * Do some bridge work that must take place before we start messing with + * the bridge for real. */ -u32 __init -mv64x60_get_mem_size(u32 bridge_base, u32 chip_type) +void __init +mv64x60_early_init(struct mv64x60_handle *bh, struct mv64x60_setup_info *si) { - mv64x60_handle_t bh; - u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]; + struct pci_controller hose_a, hose_b; - memset(&bh, 0, sizeof(bh)); + memset(bh, 0, sizeof(*bh)); - bh.type = chip_type; - bh.p_base = bridge_base; - bh.v_base = bridge_base; + bh->p_base = si->phys_reg_base; + bh->v_base = ioremap(bh->p_base, MV64x60_INTERNAL_SPACE_SIZE); + + mv64x60_bridge_pbase = bh->p_base; + mv64x60_bridge_vbase = bh->v_base; + + /* Assuming pci mode [reserved] bits 4:5 on 64260 are 0 */ + bh->pci_mode_a = mv64x60_read(bh, MV64x60_PCI0_MODE) & + MV64x60_PCIMODE_MASK; + bh->pci_mode_b = mv64x60_read(bh, MV64x60_PCI1_MODE) & + MV64x60_PCIMODE_MASK; + + /* Need temporary hose structs to call mv64x60_set_bus() */ + memset(&hose_a, 0, sizeof(hose_a)); + memset(&hose_b, 0, sizeof(hose_b)); + setup_indirect_pci_nomap(&hose_a, bh->v_base + MV64x60_PCI0_CONFIG_ADDR, + bh->v_base + MV64x60_PCI0_CONFIG_DATA); + setup_indirect_pci_nomap(&hose_b, bh->v_base + MV64x60_PCI1_CONFIG_ADDR, + bh->v_base + MV64x60_PCI1_CONFIG_DATA); + bh->hose_a = &hose_a; + bh->hose_b = &hose_b; - (void)mv64x60_setup_for_chip(&bh); - mv64x60_get_mem_windows(&bh, mem_windows); - return mv64x60_calc_mem_size(&bh, mem_windows); + mv64x60_set_bus(bh, 0, 0); + mv64x60_set_bus(bh, 1, 0); + + bh->hose_a = NULL; + bh->hose_b = NULL; + + /* Clear bit 0 of PCI addr decode control so PCI->CPU remap 1:1 */ + mv64x60_clr_bits(bh, MV64x60_PCI0_PCI_DECODE_CNTL, 0x00000001); + mv64x60_clr_bits(bh, MV64x60_PCI1_PCI_DECODE_CNTL, 0x00000001); + + /* Bit 12 MUST be 0; set bit 27--don't auto-update cpu remap regs */ + mv64x60_clr_bits(bh, MV64x60_CPU_CONFIG, (1<<12)); + mv64x60_set_bits(bh, MV64x60_CPU_CONFIG, (1<<27)); + + mv64x60_set_bits(bh, MV64x60_PCI0_TO_RETRY, 0xffff); + mv64x60_set_bits(bh, MV64x60_PCI1_TO_RETRY, 0xffff); + + return; } /* ***************************************************************************** * - * Window Config Routines (Externally Visible) + * Window Config Routines * ***************************************************************************** */ @@ -1241,12 +608,13 @@ mv64x60_get_mem_size(u32 bridge_base, u32 chip_type) * Determine the base address and size of a 32-bit window on the bridge. */ void __init -mv64x60_get_32bit_window(mv64x60_handle_t *bh, u32 window, u32 *base, u32 *size) +mv64x60_get_32bit_window(struct mv64x60_handle *bh, u32 window, + u32 *base, u32 *size) { u32 val, base_reg, size_reg, base_bits, size_bits; u32 (*get_from_field)(u32 val, u32 num_bits); - base_reg = bh->ci->window_tab_32bit[window].base_reg; + base_reg = bh->ci->window_tab_32bit[window].base_reg; if (base_reg != 0) { size_reg = bh->ci->window_tab_32bit[window].size_reg; @@ -1262,16 +630,15 @@ mv64x60_get_32bit_window(mv64x60_handle_t *bh, u32 window, u32 *base, u32 *size) val = get_from_field(val, size_bits); *size = bh->ci->untranslate_size(*base, val, size_bits); } - else { + else *size = 0; - } } else { *base = 0; *size = 0; } - DBG("get 32bit window: %d, base: 0x%x, size: 0x%x\n", + pr_debug("get 32bit window: %d, base: 0x%x, size: 0x%x\n", window, *base, *size); return; @@ -1283,16 +650,16 @@ mv64x60_get_32bit_window(mv64x60_handle_t *bh, u32 window, u32 *base, u32 *size) * Set the base address and size of a 32-bit window on the bridge. */ void __init -mv64x60_set_32bit_window(mv64x60_handle_t *bh, u32 window, u32 base, u32 size, - u32 other_bits) +mv64x60_set_32bit_window(struct mv64x60_handle *bh, u32 window, + u32 base, u32 size, u32 other_bits) { u32 val, base_reg, size_reg, base_bits, size_bits; u32 (*map_to_field)(u32 val, u32 num_bits); - DBG("set 32bit window: %d, base: 0x%x, size: 0x%x, other: 0x%x\n", + pr_debug("set 32bit window: %d, base: 0x%x, size: 0x%x, other: 0x%x\n", window, base, size, other_bits); - base_reg = bh->ci->window_tab_32bit[window].base_reg; + base_reg = bh->ci->window_tab_32bit[window].base_reg; if (base_reg != 0) { size_reg = bh->ci->window_tab_32bit[window].size_reg; @@ -1308,6 +675,7 @@ mv64x60_set_32bit_window(mv64x60_handle_t *bh, u32 window, u32 base, u32 size, val = map_to_field(val, size_bits); mv64x60_write(bh, size_reg, val); } + (void)mv64x60_read(bh, base_reg); /* Flush FIFO */ } @@ -1320,8 +688,8 @@ mv64x60_set_32bit_window(mv64x60_handle_t *bh, u32 window, u32 base, u32 size, * Determine the base address and size of a 64-bit window on the bridge. */ void __init -mv64x60_get_64bit_window(mv64x60_handle_t *bh, u32 window, u32 *base_hi, - u32 *base_lo, u32 *size) +mv64x60_get_64bit_window(struct mv64x60_handle *bh, u32 window, + u32 *base_hi, u32 *base_lo, u32 *size) { u32 val, base_lo_reg, size_reg, base_lo_bits, size_bits; u32 (*get_from_field)(u32 val, u32 num_bits); @@ -1334,7 +702,7 @@ mv64x60_get_64bit_window(mv64x60_handle_t *bh, u32 window, u32 *base_hi, size_bits = bh->ci->window_tab_64bit[window].size_bits; get_from_field= bh->ci->window_tab_64bit[window].get_from_field; - *base_hi = mv64x60_read(bh, + *base_hi = mv64x60_read(bh, bh->ci->window_tab_64bit[window].base_hi_reg); val = mv64x60_read(bh, base_lo_reg); @@ -1346,9 +714,8 @@ mv64x60_get_64bit_window(mv64x60_handle_t *bh, u32 window, u32 *base_hi, *size = bh->ci->untranslate_size(*base_lo, val, size_bits); } - else { + else *size = 0; - } } else { *base_hi = 0; @@ -1356,8 +723,8 @@ mv64x60_get_64bit_window(mv64x60_handle_t *bh, u32 window, u32 *base_hi, *size = 0; } - DBG("get 64bit window: %d, base hi: 0x%x, base lo: 0x%x, size: 0x%x\n", - window, *base_hi, *base_lo, *size); + pr_debug("get 64bit window: %d, base hi: 0x%x, base lo: 0x%x, " + "size: 0x%x\n", window, *base_hi, *base_lo, *size); return; } @@ -1368,13 +735,13 @@ mv64x60_get_64bit_window(mv64x60_handle_t *bh, u32 window, u32 *base_hi, * Set the base address and size of a 64-bit window on the bridge. */ void __init -mv64x60_set_64bit_window(mv64x60_handle_t *bh, u32 window, - u32 base_hi, u32 base_lo, u32 size, u32 other_bits) +mv64x60_set_64bit_window(struct mv64x60_handle *bh, u32 window, + u32 base_hi, u32 base_lo, u32 size, u32 other_bits) { u32 val, base_lo_reg, size_reg, base_lo_bits, size_bits; u32 (*map_to_field)(u32 val, u32 num_bits); - DBG("set 64bit window: %d, base hi: 0x%x, base lo: 0x%x, " \ + pr_debug("set 64bit window: %d, base hi: 0x%x, base lo: 0x%x, " "size: 0x%x, other: 0x%x\n", window, base_hi, base_lo, size, other_bits); @@ -1409,26 +776,20 @@ mv64x60_set_64bit_window(mv64x60_handle_t *bh, u32 window, * * Take the high-order 'num_bits' of 'val' & mask off low bits. */ -static u32 __init +u32 __init mv64x60_mask(u32 val, u32 num_bits) { - DBG("mask val: 0x%x, num_bits: %d == 0x%x\n", val, - num_bits, val & (0xffffffff << (32 - num_bits))); - return val & (0xffffffff << (32 - num_bits)); } /* - * mv64x60_mask_shift_left() + * mv64x60_shift_left() * * Take the low-order 'num_bits' of 'val', shift left to align at bit 31 (MSB). */ -static u32 __init +u32 __init mv64x60_shift_left(u32 val, u32 num_bits) { - DBG("shift left val: 0x%x, num_bits: %d == 0x%x\n", val, - num_bits, val << (32 - num_bits)); - return val << (32 - num_bits); } @@ -1437,61 +798,12 @@ mv64x60_shift_left(u32 val, u32 num_bits) * * Take the high-order 'num_bits' of 'val', shift right to align at bit 0 (LSB). */ -static u32 __init +u32 __init mv64x60_shift_right(u32 val, u32 num_bits) { - DBG("shift right val: 0x%x, num_bits: %d == 0x%x\n", val, num_bits, - val >> (32 - num_bits)); - return val >> (32 - num_bits); } -/* - ***************************************************************************** - * - * Early Init Routines - * - ***************************************************************************** - */ -/* - * mv64x60_early_init() - * - * Do some bridge work that must take place before we start messing with - * the bridge for real. - */ -static void __init -mv64x60_early_init(mv64x60_handle_t *bh, mv64x60_setup_info_t *si) -{ - memset(bh, 0, sizeof(*bh)); - - bh->p_base = si->phys_reg_base; - bh->v_base = (u32)ioremap(bh->p_base, MV64x60_INTERNAL_SPACE_SIZE); - bh->base_irq = si->base_irq; - - /* Bit 12 MUST be 0; set bit 27--don't auto-update cpu remap regs */ - mv64x60_clr_bits(bh, MV64x60_CPU_CONFIG, (1<<12)); - mv64x60_set_bits(bh, MV64x60_CPU_CONFIG, (1<<27)); - - /* - * Turn off timer/counters. Not turning off watchdog timer because - * can't read its reg on the 64260A so don't know if we'll be enabling - * or disabling. - */ - mv64x60_clr_bits(bh, MV64x60_TIMR_CNTR_0_3_CNTL, - ((1<<0) | (1<<8) | (1<<16) | (1<<24))); - -#ifdef CONFIG_GT64260 - mv64x60_clr_bits(bh, GT64260_TIMR_CNTR_4_7_CNTL, - ((1<<0) | (1<<8) | (1<<16) | (1<<24))); -#endif - -#if 0 -XXXX Put in PCI_x_RETRY adjustment XXXX -#endif - - return; -} - /* ***************************************************************************** * @@ -1504,38 +816,47 @@ XXXX Put in PCI_x_RETRY adjustment XXXX * * Determine the type of bridge chip we have. */ -static int __init mv64x60_get_type(struct mv64x60_handle *bh) +int __init +mv64x60_get_type(struct mv64x60_handle *bh) { - struct pci_controller *hose = bh->hose_a; - int pcidev; - int devfn; - u16 val; - u8 save_exclude; + struct pci_controller hose; + u16 val; + u8 save_exclude; - pcidev = (mv64x60_read(bh, MV64x60_PCI0_P2P_CONFIG) >> 24) & 0xf; - devfn = PCI_DEVFN(pcidev, 0); + memset(&hose, 0, sizeof(hose)); + setup_indirect_pci_nomap(&hose, bh->v_base + MV64x60_PCI0_CONFIG_ADDR, + bh->v_base + MV64x60_PCI0_CONFIG_DATA); save_exclude = mv64x60_pci_exclude_bridge; - mv64x60_pci_exclude_bridge = FALSE; - + mv64x60_pci_exclude_bridge = 0; /* Sanity check of bridge's Vendor ID */ - early_read_config_word(hose, 0, devfn, PCI_VENDOR_ID, &val); + early_read_config_word(&hose, 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID, &val); - if (val != PCI_VENDOR_ID_MARVELL) + if (val != PCI_VENDOR_ID_MARVELL) { + mv64x60_pci_exclude_bridge = save_exclude; return -1; + } + + /* Get the revision of the chip */ + early_read_config_word(&hose, 0, PCI_DEVFN(0, 0), PCI_CLASS_REVISION, + &val); + bh->rev = (u32)(val & 0xff); /* Figure out the type of Marvell bridge it is */ - early_read_config_word(hose, 0, devfn, PCI_DEVICE_ID, &val); + early_read_config_word(&hose, 0, PCI_DEVFN(0, 0), PCI_DEVICE_ID, &val); + mv64x60_pci_exclude_bridge = save_exclude; switch (val) { case PCI_DEVICE_ID_MARVELL_GT64260: - early_read_config_word(hose, 0, devfn, - PCI_CLASS_REVISION, &val); - - switch (val & 0xff) { + switch (bh->rev) { case GT64260_REV_A: bh->type = MV64x60_TYPE_GT64260A; break; + + default: + printk(KERN_WARNING "Unsupported GT64260 rev %04x\n", + bh->rev); + /* Assume its similar to a 'B' rev and fallthru */ case GT64260_REV_B: bh->type = MV64x60_TYPE_GT64260B; break; @@ -1552,11 +873,14 @@ static int __init mv64x60_get_type(struct mv64x60_handle *bh) break; default: - printk(KERN_CRIT "Unknown Marvell bridge type %04x\n", val); + printk(KERN_ERR "Unknown Marvell bridge type %04x\n", val); return -1; } - mv64x60_pci_exclude_bridge = save_exclude; + /* Hang onto bridge type & rev for PIC code */ + mv64x60_bridge_type = bh->type; + mv64x60_bridge_rev = bh->rev; + return 0; } @@ -1565,45 +889,73 @@ static int __init mv64x60_get_type(struct mv64x60_handle *bh) * * Set 'bh' to use the proper set of routine for the bridge chip that we have. */ -static int __init -mv64x60_setup_for_chip(mv64x60_handle_t *bh) +int __init +mv64x60_setup_for_chip(struct mv64x60_handle *bh) { int rc = 0; /* Set up chip-specific info based on the chip/bridge type */ switch(bh->type) { - case MV64x60_TYPE_GT64260A: - bh->ci = >64260a_ci; - break; + case MV64x60_TYPE_GT64260A: + bh->ci = >64260a_ci; + break; - case MV64x60_TYPE_GT64260B: - bh->ci = >64260b_ci; - break; + case MV64x60_TYPE_GT64260B: + bh->ci = >64260b_ci; + break; - case MV64x60_TYPE_MV64360: - bh->ci = &mv64360_ci; - break; + case MV64x60_TYPE_MV64360: + bh->ci = &mv64360_ci; + break; -#if 0 /* Marvell won't tell me how to distinguish--MAG */ - case MV64x60_TYPE_MV64361: - case MV64x60_TYPE_MV64362: -#endif - case MV64x60_TYPE_MV64460: - bh->ci = &mv64460_ci; - break; + case MV64x60_TYPE_MV64460: + bh->ci = &mv64460_ci; + break; - case MV64x60_TYPE_INVALID: - default: - if (ppc_md.progress) - ppc_md.progress("mv64x60: Unsupported bridge", - 0x0); - printk("mv64x60: Unsupported bridge\n"); - rc = -1; + case MV64x60_TYPE_INVALID: + default: + if (ppc_md.progress) + ppc_md.progress("mv64x60: Unsupported bridge", 0x0); + printk(KERN_ERR "mv64x60: Unsupported bridge\n"); + rc = -1; } return rc; } +/* + * mv64x60_get_bridge_vbase() + * + * Return the virtual address of the bridge's registers. + */ +void * +mv64x60_get_bridge_vbase(void) +{ + return mv64x60_bridge_vbase; +} + +/* + * mv64x60_get_bridge_type() + * + * Return the type of bridge on the platform. + */ +u32 +mv64x60_get_bridge_type(void) +{ + return mv64x60_bridge_type; +} + +/* + * mv64x60_get_bridge_rev() + * + * Return the revision of the bridge on the platform. + */ +u32 +mv64x60_get_bridge_rev(void) +{ + return mv64x60_bridge_rev; +} + /* ***************************************************************************** * @@ -1611,29 +963,52 @@ mv64x60_setup_for_chip(mv64x60_handle_t *bh) * ***************************************************************************** */ +/* + * mv64x60_get_mem_size() + * + * Calculate the amount of memory that the memory controller is set up for. + * This should only be used by board-specific code if there is no other + * way to determine the amount of memory in the system. + */ +u32 __init +mv64x60_get_mem_size(u32 bridge_base, u32 chip_type) +{ + struct mv64x60_handle bh; + u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]; + u32 rc = 0; + + memset(&bh, 0, sizeof(bh)); + + bh.type = chip_type; + bh.v_base = (void *)bridge_base; + + if (!mv64x60_setup_for_chip(&bh)) { + mv64x60_get_mem_windows(&bh, mem_windows); + rc = mv64x60_calc_mem_size(&bh, mem_windows); + } + + return rc; +} + /* * mv64x60_get_mem_windows() * * Get the values in the memory controller & return in the 'mem_windows' array. */ -static void __init -mv64x60_get_mem_windows(mv64x60_handle_t *bh, +void __init +mv64x60_get_mem_windows(struct mv64x60_handle *bh, u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]) { - u32 i; - u32 windows[] = { MV64x60_CPU2MEM_0_WIN, MV64x60_CPU2MEM_1_WIN, - MV64x60_CPU2MEM_2_WIN, MV64x60_CPU2MEM_3_WIN }; + u32 i, win; - for (i=0; ici->is_enabled_32bit(bh, i)) { - mv64x60_get_32bit_window(bh, windows[i], + for (win=MV64x60_CPU2MEM_0_WIN,i=0;win<=MV64x60_CPU2MEM_3_WIN;win++,i++) + if (bh->ci->is_enabled_32bit(bh, win)) + mv64x60_get_32bit_window(bh, win, &mem_windows[i][0], &mem_windows[i][1]); - } else { mem_windows[i][0] = 0; mem_windows[i][1] = 0; } - } return; } @@ -1644,15 +1019,14 @@ mv64x60_get_mem_windows(mv64x60_handle_t *bh, * Using the memory controller register values in 'mem_windows', determine * how much memory it is set up for. */ -static u32 __init -mv64x60_calc_mem_size(mv64x60_handle_t *bh, +u32 __init +mv64x60_calc_mem_size(struct mv64x60_handle *bh, u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]) { u32 i, total = 0; - for (i=0; iSystem MEM Config Routines + * CPU->System MEM, PCI Config Routines * ***************************************************************************** */ @@ -1669,131 +1043,92 @@ mv64x60_calc_mem_size(mv64x60_handle_t *bh, * * Configure CPU->Memory windows on the bridge. */ -static void __init -mv64x60_config_cpu2mem_windows(mv64x60_handle_t *bh, mv64x60_setup_info_t *si, +static u32 prot_tab[] __initdata = { + MV64x60_CPU_PROT_0_WIN, MV64x60_CPU_PROT_1_WIN, + MV64x60_CPU_PROT_2_WIN, MV64x60_CPU_PROT_3_WIN +}; + +static u32 cpu_snoop_tab[] __initdata = { + MV64x60_CPU_SNOOP_0_WIN, MV64x60_CPU_SNOOP_1_WIN, + MV64x60_CPU_SNOOP_2_WIN, MV64x60_CPU_SNOOP_3_WIN +}; + +void __init +mv64x60_config_cpu2mem_windows(struct mv64x60_handle *bh, + struct mv64x60_setup_info *si, u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]) { - u32 i; - u32 prot_windows[] = { - MV64x60_CPU_PROT_0_WIN, MV64x60_CPU_PROT_1_WIN, - MV64x60_CPU_PROT_2_WIN, MV64x60_CPU_PROT_3_WIN }; - u32 cpu_snoop_windows[] = { - MV64x60_CPU_SNOOP_0_WIN, MV64x60_CPU_SNOOP_1_WIN, - MV64x60_CPU_SNOOP_2_WIN, MV64x60_CPU_SNOOP_3_WIN }; + u32 i, win; /* Set CPU protection & snoop windows */ - for (i=0; ici->is_enabled_32bit(bh, i)) { - mv64x60_set_32bit_window(bh, prot_windows[i], + 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, prot_tab[i], mem_windows[i][0], mem_windows[i][1], si->cpu_prot_options[i]); - bh->ci->enable_window_32bit(bh, prot_windows[i]); + bh->ci->enable_window_32bit(bh, prot_tab[i]); - if (bh->ci->window_tab_32bit[cpu_snoop_windows[i]]. + if (bh->ci->window_tab_32bit[cpu_snoop_tab[i]]. base_reg != 0) { - mv64x60_set_32bit_window(bh, - cpu_snoop_windows[i], mem_windows[i][0], - mem_windows[i][1], + mv64x60_set_32bit_window(bh, cpu_snoop_tab[i], + mem_windows[i][0], mem_windows[i][1], si->cpu_snoop_options[i]); bh->ci->enable_window_32bit(bh, - cpu_snoop_windows[i]); + cpu_snoop_tab[i]); } } - } return; } -/* - ***************************************************************************** - * - * CPU->PCI Config Routines - * - ***************************************************************************** - */ - /* * mv64x60_config_cpu2pci_windows() * - * Configure the CPU->PCI windows on the bridge. + * Configure the CPU->PCI windows for one of the PCI buses. */ -static void __init -mv64x60_config_cpu2pci_windows(mv64x60_handle_t *bh, mv64x60_setup_info_t *si) -{ - if (ppc_md.progress) - ppc_md.progress("mv64x60_config_bridge: Enter", 0x0); - - /* - * Set up various parts of the bridge including CPU->PCI windows. - * Depending on the board, there may be only one hose that needs to - * be set up. - */ - if (si->pci_0.enable_bus) { - u32 win_tab[] = { MV64x60_CPU2PCI0_IO_WIN, - MV64x60_CPU2PCI0_MEM_0_WIN, - MV64x60_CPU2PCI0_MEM_1_WIN, - MV64x60_CPU2PCI0_MEM_2_WIN }; - u32 remap_tab[] = { MV64x60_CPU2PCI0_IO_REMAP_WIN, - MV64x60_CPU2PCI0_MEM_0_REMAP_WIN, - MV64x60_CPU2PCI0_MEM_1_REMAP_WIN, - MV64x60_CPU2PCI0_MEM_2_REMAP_WIN }; - - mv64x60_set_cpu2pci_window(bh, &si->pci_0, win_tab, remap_tab); - } - - if (si->pci_1.enable_bus) { - u32 win_tab[] = { MV64x60_CPU2PCI1_IO_WIN, - MV64x60_CPU2PCI1_MEM_0_WIN, - MV64x60_CPU2PCI1_MEM_1_WIN, - MV64x60_CPU2PCI1_MEM_2_WIN }; - u32 remap_tab[] = { MV64x60_CPU2PCI1_IO_REMAP_WIN, - MV64x60_CPU2PCI1_MEM_0_REMAP_WIN, - MV64x60_CPU2PCI1_MEM_1_REMAP_WIN, - MV64x60_CPU2PCI1_MEM_2_REMAP_WIN }; - - mv64x60_set_cpu2pci_window(bh, &si->pci_1, win_tab, remap_tab); - } +static u32 win_tab[2][4] __initdata = { + { MV64x60_CPU2PCI0_IO_WIN, MV64x60_CPU2PCI0_MEM_0_WIN, + MV64x60_CPU2PCI0_MEM_1_WIN, MV64x60_CPU2PCI0_MEM_2_WIN }, + { MV64x60_CPU2PCI1_IO_WIN, MV64x60_CPU2PCI1_MEM_0_WIN, + MV64x60_CPU2PCI1_MEM_1_WIN, MV64x60_CPU2PCI1_MEM_2_WIN }, +}; - return; -} /* mv64x60_config_bridge() */ +static u32 remap_tab[2][4] __initdata = { + { MV64x60_CPU2PCI0_IO_REMAP_WIN, MV64x60_CPU2PCI0_MEM_0_REMAP_WIN, + MV64x60_CPU2PCI0_MEM_1_REMAP_WIN, MV64x60_CPU2PCI0_MEM_2_REMAP_WIN }, + { MV64x60_CPU2PCI1_IO_REMAP_WIN, MV64x60_CPU2PCI1_MEM_0_REMAP_WIN, + MV64x60_CPU2PCI1_MEM_1_REMAP_WIN, MV64x60_CPU2PCI1_MEM_2_REMAP_WIN } +}; -/* - * mv64x60_set_cpu2pci_window() - * - * Configure the CPU->PCI windows for one of the PCI buses. - */ -static void __init -mv64x60_set_cpu2pci_window(mv64x60_handle_t *bh, mv64x60_pci_info_t *pi, - u32 *win_tab, u32 *remap_tab) +void __init +mv64x60_config_cpu2pci_windows(struct mv64x60_handle *bh, + struct mv64x60_pci_info *pi, u32 bus) { int i; if (pi->pci_io.size > 0) { - mv64x60_set_32bit_window(bh, win_tab[0], pi->pci_io.cpu_base, - pi->pci_io.size, pi->pci_io.swap); - mv64x60_set_32bit_window(bh, remap_tab[0], - pi->pci_io.pci_base_lo, 0, 0); - bh->ci->enable_window_32bit(bh, win_tab[0]); - } - else { /* Actually, the window should already be disabled */ - bh->ci->disable_window_32bit(bh, win_tab[0]); + mv64x60_set_32bit_window(bh, win_tab[bus][0], + pi->pci_io.cpu_base, pi->pci_io.size, pi->pci_io.swap); + mv64x60_set_32bit_window(bh, remap_tab[bus][0], + pi->pci_io.pci_base_lo, 0, 0); + bh->ci->enable_window_32bit(bh, win_tab[bus][0]); } + else /* Actually, the window should already be disabled */ + bh->ci->disable_window_32bit(bh, win_tab[bus][0]); - for (i=0; i<3; i++) { + for (i=0; i<3; i++) if (pi->pci_mem[i].size > 0) { - mv64x60_set_32bit_window(bh, win_tab[i+1], + mv64x60_set_32bit_window(bh, win_tab[bus][i+1], pi->pci_mem[i].cpu_base, pi->pci_mem[i].size, pi->pci_mem[i].swap); - mv64x60_set_64bit_window(bh, remap_tab[i+1], + mv64x60_set_64bit_window(bh, remap_tab[bus][i+1], pi->pci_mem[i].pci_base_hi, pi->pci_mem[i].pci_base_lo, 0, 0); - bh->ci->enable_window_32bit(bh, win_tab[i+1]); - } - else { /* Actually, the window should already be disabled */ - bh->ci->disable_window_32bit(bh, win_tab[i+1]); + bh->ci->enable_window_32bit(bh, win_tab[bus][i+1]); } - } + else /* Actually, the window should already be disabled */ + bh->ci->disable_window_32bit(bh, win_tab[bus][i+1]); return; } @@ -1810,109 +1145,68 @@ mv64x60_set_cpu2pci_window(mv64x60_handle_t *bh, mv64x60_pci_info_t *pi, * * Configure the PCI->Memory windows on the bridge. */ -static void __init -mv64x60_config_pci2mem_windows(mv64x60_handle_t *bh, mv64x60_setup_info_t *si, - u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]) -{ - u32 i; - u32 pci_0_acc_windows[] = { - MV64x60_PCI02MEM_ACC_CNTL_0_WIN, - MV64x60_PCI02MEM_ACC_CNTL_1_WIN, - MV64x60_PCI02MEM_ACC_CNTL_2_WIN, - MV64x60_PCI02MEM_ACC_CNTL_3_WIN }; - u32 pci_1_acc_windows[] = { - MV64x60_PCI12MEM_ACC_CNTL_0_WIN, - MV64x60_PCI12MEM_ACC_CNTL_1_WIN, - MV64x60_PCI12MEM_ACC_CNTL_2_WIN, - MV64x60_PCI12MEM_ACC_CNTL_3_WIN }; - u32 pci_0_snoop_windows[] = { - MV64x60_PCI02MEM_SNOOP_0_WIN, - MV64x60_PCI02MEM_SNOOP_1_WIN, - MV64x60_PCI02MEM_SNOOP_2_WIN, - MV64x60_PCI02MEM_SNOOP_3_WIN }; - u32 pci_1_snoop_windows[] = { - MV64x60_PCI12MEM_SNOOP_0_WIN, - MV64x60_PCI12MEM_SNOOP_1_WIN, - MV64x60_PCI12MEM_SNOOP_2_WIN, - MV64x60_PCI12MEM_SNOOP_3_WIN }; - u32 pci_0_size[] = { - MV64x60_PCI0_MEM_0_SIZE, MV64x60_PCI0_MEM_1_SIZE, - MV64x60_PCI0_MEM_2_SIZE, MV64x60_PCI0_MEM_3_SIZE }; - u32 pci_1_size[] = { - MV64x60_PCI1_MEM_0_SIZE, MV64x60_PCI1_MEM_1_SIZE, - MV64x60_PCI1_MEM_2_SIZE, MV64x60_PCI1_MEM_3_SIZE }; +static u32 pci_acc_tab[2][4] __initdata = { + { MV64x60_PCI02MEM_ACC_CNTL_0_WIN, MV64x60_PCI02MEM_ACC_CNTL_1_WIN, + MV64x60_PCI02MEM_ACC_CNTL_2_WIN, MV64x60_PCI02MEM_ACC_CNTL_3_WIN }, + { MV64x60_PCI12MEM_ACC_CNTL_0_WIN, MV64x60_PCI12MEM_ACC_CNTL_1_WIN, + MV64x60_PCI12MEM_ACC_CNTL_2_WIN, MV64x60_PCI12MEM_ACC_CNTL_3_WIN } +}; - /* Clear bit 0 of PCI addr decode control so PCI->CPU remap 1:1 */ - mv64x60_clr_bits(bh, MV64x60_PCI0_PCI_DECODE_CNTL, 0x00000001); - mv64x60_clr_bits(bh, MV64x60_PCI1_PCI_DECODE_CNTL, 0x00000001); +static u32 pci_snoop_tab[2][4] __initdata = { + { MV64x60_PCI02MEM_SNOOP_0_WIN, MV64x60_PCI02MEM_SNOOP_1_WIN, + MV64x60_PCI02MEM_SNOOP_2_WIN, MV64x60_PCI02MEM_SNOOP_3_WIN }, + { MV64x60_PCI12MEM_SNOOP_0_WIN, MV64x60_PCI12MEM_SNOOP_1_WIN, + MV64x60_PCI12MEM_SNOOP_2_WIN, MV64x60_PCI12MEM_SNOOP_3_WIN } +}; + +static u32 pci_size_tab[2][4] __initdata = { + { MV64x60_PCI0_MEM_0_SIZE, MV64x60_PCI0_MEM_1_SIZE, + MV64x60_PCI0_MEM_2_SIZE, MV64x60_PCI0_MEM_3_SIZE }, + { MV64x60_PCI1_MEM_0_SIZE, MV64x60_PCI1_MEM_1_SIZE, + MV64x60_PCI1_MEM_2_SIZE, MV64x60_PCI1_MEM_3_SIZE } +}; + +void __init +mv64x60_config_pci2mem_windows(struct mv64x60_handle *bh, + struct pci_controller *hose, struct mv64x60_pci_info *pi, + u32 bus, u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]) +{ + u32 i, win; /* * Set the access control, snoop, BAR size, and window base addresses. * PCI->MEM windows base addresses will match exactly what the * CPU->MEM windows are. */ - for (i=0; ici->is_enabled_32bit(bh, i)) { - if (si->pci_0.enable_bus) { - mv64x60_set_64bit_window(bh, - pci_0_acc_windows[i], 0, - mem_windows[i][0], mem_windows[i][1], - si->pci_0.acc_cntl_options[i]); - bh->ci->enable_window_64bit(bh, - pci_0_acc_windows[i]); - - if (bh->ci->window_tab_64bit[ - pci_0_snoop_windows[i]].base_lo_reg - != 0) { - mv64x60_set_64bit_window(bh, - pci_0_snoop_windows[i], 0, - mem_windows[i][0], - mem_windows[i][1], - si->pci_0.snoop_options[i]); - bh->ci->enable_window_64bit(bh, - pci_0_snoop_windows[i]); - } - - bh->ci->set_pci2mem_window(bh->hose_a, i, - mem_windows[i][0]); - mv64x60_write(bh, pci_0_size[i], - mv64x60_mask(mem_windows[i][1] -1, 20)); - - /* Enable the window */ - mv64x60_clr_bits(bh, MV64x60_PCI0_BAR_ENABLE, - 1 << i); - } - if (si->pci_1.enable_bus) { + 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_64bit_window(bh, + pci_acc_tab[bus][i], 0, + mem_windows[i][0], mem_windows[i][1], + pi->acc_cntl_options[i]); + bh->ci->enable_window_64bit(bh, pci_acc_tab[bus][i]); + + if (bh->ci->window_tab_64bit[ + pci_snoop_tab[bus][i]].base_lo_reg != 0) { + mv64x60_set_64bit_window(bh, - pci_1_acc_windows[i], 0, + pci_snoop_tab[bus][i], 0, mem_windows[i][0], mem_windows[i][1], - si->pci_1.acc_cntl_options[i]); + pi->snoop_options[i]); bh->ci->enable_window_64bit(bh, - pci_1_acc_windows[i]); - - if (bh->ci->window_tab_64bit[ - pci_1_snoop_windows[i]].base_lo_reg - != 0) { - mv64x60_set_64bit_window(bh, - pci_1_snoop_windows[i], 0, - mem_windows[i][0], - mem_windows[i][1], - si->pci_1.snoop_options[i]); - bh->ci->enable_window_64bit(bh, - pci_1_snoop_windows[i]); - } - - bh->ci->set_pci2mem_window(bh->hose_b, i, - mem_windows[i][0]); - mv64x60_write(bh, pci_1_size[i], - mv64x60_mask(mem_windows[i][1] -1, 20)); - - /* Enable the window */ - mv64x60_clr_bits(bh, MV64x60_PCI1_BAR_ENABLE, - 1 << i); + pci_snoop_tab[bus][i]); } + + bh->ci->set_pci2mem_window(hose, bus, i, + mem_windows[i][0]); + mv64x60_write(bh, pci_size_tab[bus][i], + mv64x60_mask(mem_windows[i][1] - 1, 20)); + + /* Enable the window */ + mv64x60_clr_bits(bh, ((bus == 0) ? + MV64x60_PCI0_BAR_ENABLE : + MV64x60_PCI1_BAR_ENABLE), (1 << i)); } - } return; } @@ -1929,72 +1223,28 @@ mv64x60_config_pci2mem_windows(mv64x60_handle_t *bh, mv64x60_setup_info_t *si, * * Allocate the PCI hose structures for the bridge's PCI buses. */ -static void __init -mv64x60_alloc_hoses(mv64x60_handle_t *bh, mv64x60_setup_info_t *si) -{ - /* - * Alloc first hose struct even when its not to be configured b/c the - * chip identification routines need to use it. - */ - bh->hose_a = pcibios_alloc_controller(); - setup_indirect_pci(bh->hose_a, - bh->p_base + MV64x60_PCI0_CONFIG_ADDR, - bh->p_base + MV64x60_PCI0_CONFIG_DATA); - - if (si->pci_1.enable_bus) { - bh->hose_b = pcibios_alloc_controller(); - setup_indirect_pci(bh->hose_b, - bh->p_base + MV64x60_PCI1_CONFIG_ADDR, - bh->p_base + MV64x60_PCI1_CONFIG_DATA); - } - - return; -} - -/* - * mv64x60_init_hoses() - * - * Initialize the PCI hose structures for the bridge's PCI hoses. - */ -static void __init -mv64x60_init_hoses(mv64x60_handle_t *bh, mv64x60_setup_info_t *si) +void __init +mv64x60_alloc_hose(struct mv64x60_handle *bh, u32 cfg_addr, u32 cfg_data, + struct pci_controller **hose) { - if (si->pci_1.enable_bus) { - bh->io_base_b = (u32)ioremap(si->pci_1.pci_io.cpu_base, - si->pci_1.pci_io.size); - isa_io_base = bh->io_base_b; - } - - if (si->pci_0.enable_bus) { - bh->io_base_a = (u32)ioremap(si->pci_0.pci_io.cpu_base, - si->pci_0.pci_io.size); - isa_io_base = bh->io_base_a; - - mv64x60_init_resources(bh->hose_a, &si->pci_0, bh->io_base_a); - mv64x60_set_pci_params(bh->hose_a, &si->pci_0); - } - - /* Must do here so proper isa_io_base is used in calculations */ - if (si->pci_1.enable_bus) { - mv64x60_init_resources(bh->hose_b, &si->pci_1, bh->io_base_b); - mv64x60_set_pci_params(bh->hose_b, &si->pci_1); - } - + *hose = pcibios_alloc_controller(); + setup_indirect_pci_nomap(*hose, bh->v_base + cfg_addr, + bh->v_base + cfg_data); return; } /* - * mv64x60_init_resources() + * mv64x60_config_resources() * * Calculate the offsets, etc. for the hose structures to reflect all of * the address remapping that happens as you go from CPU->PCI and PCI->MEM. */ -static void __init -mv64x60_init_resources(struct pci_controller *hose, mv64x60_pci_info_t *pi, - u32 io_base) +void __init +mv64x60_config_resources(struct pci_controller *hose, + struct mv64x60_pci_info *pi, u32 io_base) { int i; - /* 2 hoses; 4 resources/hose; sting <= 64 bytes; not work if > 1 chip */ + /* 2 hoses; 4 resources/hose; string <= 64 bytes */ static char s[2][4][64]; if (pi->pci_io.size != 0) { @@ -2005,10 +1255,11 @@ mv64x60_init_resources(struct pci_controller *hose, mv64x60_pci_info_t *pi, IORESOURCE_IO, s[hose->index][0]); hose->io_space.start = pi->pci_io.pci_base_lo; hose->io_space.end = pi->pci_io.pci_base_lo + pi->pci_io.size-1; + hose->io_base_phys = pi->pci_io.cpu_base; hose->io_base_virt = (void *)isa_io_base; } - for (i=0; i<3; i++) { + for (i=0; i<3; i++) if (pi->pci_mem[i].size != 0) { sprintf(s[hose->index][i+1], "PCI hose %d MEM Space %d", hose->index, i); @@ -2017,23 +1268,22 @@ mv64x60_init_resources(struct pci_controller *hose, mv64x60_pci_info_t *pi, pi->pci_mem[i].cpu_base + pi->pci_mem[i].size-1, IORESOURCE_MEM, s[hose->index][i+1]); } - } - + hose->mem_space.end = pi->pci_mem[0].pci_base_lo + pi->pci_mem[0].size - 1; hose->pci_mem_offset = pi->pci_mem[0].cpu_base - pi->pci_mem[0].pci_base_lo; - return; -} /* mv64x60_init_resources() */ +} /* - * mv64x60_set_pci_params() + * mv64x60_config_pci_params() * * Configure a hose's PCI config space parameters. */ -static void __init -mv64x60_set_pci_params(struct pci_controller *hose, mv64x60_pci_info_t *pi) +void __init +mv64x60_config_pci_params(struct pci_controller *hose, + struct mv64x60_pci_info *pi) { u32 devfn; u16 u16_val; @@ -2042,13 +1292,13 @@ mv64x60_set_pci_params(struct pci_controller *hose, mv64x60_pci_info_t *pi) devfn = PCI_DEVFN(0,0); save_exclude = mv64x60_pci_exclude_bridge; - mv64x60_pci_exclude_bridge = FALSE; + mv64x60_pci_exclude_bridge = 0; /* Set class code to indicate host bridge */ u16_val = PCI_CLASS_BRIDGE_HOST; /* 0x0600 (host bridge) */ early_write_config_word(hose, 0, devfn, PCI_CLASS_DEVICE, u16_val); - /* Enable 64260 to be PCI master & respond to PCI MEM cycles */ + /* Enable bridge to be PCI master & respond to PCI MEM cycles */ early_read_config_word(hose, 0, devfn, PCI_COMMAND, &u16_val); u16_val &= ~(PCI_COMMAND_IO | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK); @@ -2071,99 +1321,62 @@ mv64x60_set_pci_params(struct pci_controller *hose, mv64x60_pci_info_t *pi) ***************************************************************************** */ /* - * mv64x60_enumerate_buses() + * mv64x60_set_bus() * - * If requested, enumerate the PCI buses and set the appropriate - * info in the hose structures. + * Set the bus number for the hose directly under the bridge. */ -static void __init -mv64x60_enumerate_buses(mv64x60_handle_t *bh, mv64x60_setup_info_t *si) +void __init +mv64x60_set_bus(struct mv64x60_handle *bh, u32 bus, u32 child_bus) { - u32 val; - - pci_dram_offset = 0; /* System mem at same addr on PCI & cpu bus */ - - ppc_md.pci_exclude_device = mv64x60_pci_exclude_device; - ppc_md.pci_swizzle = common_swizzle; - ppc_md.pci_map_irq = si->map_irq; - - /* Now that the bridge is set up, its safe to scan the PCI buses */ - if (si->pci_0.enable_bus) { - if (si->pci_0.enumerate_bus) { - /* Set bus number for PCI 0 to 0 */ - val = mv64x60_read(bh, MV64x60_PCI0_P2P_CONFIG); - val &= 0xe0000000; - val |= 0x000000ff; - mv64x60_write(bh, MV64x60_PCI0_P2P_CONFIG, val); - /* Flush FIFO*/ - (void)mv64x60_read(bh, MV64x60_PCI0_P2P_CONFIG); - -#if 0 -XXXX Different if in PCI-X mode (look at mv64360_find_bridges()) XXXX -#endif - - bh->hose_a->first_busno = 0; - bh->hose_a->last_busno = 0xff; + struct pci_controller *hose; + u32 pci_mode, p2p_cfg, pci_cfg_offset, val; + u8 save_exclude; - bh->hose_a->last_busno = pciauto_bus_scan(bh->hose_a, - bh->hose_a->first_busno); - } - else { - /* Assume bridge set up correctly by someone else */ - val = mv64x60_read(bh, MV64x60_PCI0_P2P_CONFIG); - bh->hose_a->first_busno = (val & 0x00ff0000) >> 16; - } + if (bus == 0) { + pci_mode = bh->pci_mode_a; + p2p_cfg = MV64x60_PCI0_P2P_CONFIG; + pci_cfg_offset = 0x64; + hose = bh->hose_a; + } + else { + pci_mode = bh->pci_mode_b; + p2p_cfg = MV64x60_PCI1_P2P_CONFIG; + pci_cfg_offset = 0xe4; + hose = bh->hose_b; } - if (si->pci_1.enable_bus) { - if (si->pci_1.enumerate_bus) { - if (si->pci_0.enable_bus) { - bh->hose_b->first_busno = - bh->hose_a->last_busno + 1; - - /* Set bus number for PCI 1 hose */ - val = mv64x60_read(bh, MV64x60_PCI1_P2P_CONFIG); - val &= 0xe0000000; - val |= (bh->hose_b->first_busno << 16) | 0xff; - mv64x60_write(bh, MV64x60_PCI1_P2P_CONFIG, val); - /* Flush FIFO */ - (void)mv64x60_read(bh, MV64x60_PCI1_P2P_CONFIG); - } - else { - bh->hose_b->first_busno = 0; - } + child_bus &= 0xff; + val = mv64x60_read(bh, p2p_cfg); - bh->hose_b->last_busno = 0xff; - bh->hose_b->last_busno = pciauto_bus_scan(bh->hose_b, - bh->hose_b->first_busno); - } - else { - /* Assume bridge set up correctly by someone else */ - val = mv64x60_read(bh, MV64x60_PCI1_P2P_CONFIG); - bh->hose_b->first_busno = (val & 0x00ff0000) >> 16; - bh->hose_b->last_busno = 0xff; /* No way to know */ - } + if (pci_mode == MV64x60_PCIMODE_CONVENTIONAL) { + val &= 0xe0000000; /* Force dev num to 0, turn off P2P bridge */ + val |= (child_bus << 16) | 0xff; + mv64x60_write(bh, p2p_cfg, val); + (void)mv64x60_read(bh, p2p_cfg); /* Flush FIFO */ } - - if (si->pci_0.enable_bus && !si->pci_0.enumerate_bus) { - if (si->pci_1.enable_bus) { - bh->hose_a->last_busno = bh->hose_b->first_busno - 1; - } - else { - bh->hose_a->last_busno = 0xff; /* No way to know */ - } + else { /* PCI-X */ + /* + * Need to use the current bus/dev number (that's in the + * P2P CONFIG reg) to access the bridge's pci config space. + */ + save_exclude = mv64x60_pci_exclude_bridge; + mv64x60_pci_exclude_bridge = 0; + early_write_config_dword(hose, (val & 0x00ff0000) >> 16, + PCI_DEVFN(((val & 0x1f000000) >> 24), 0), + pci_cfg_offset, child_bus << 8); + mv64x60_pci_exclude_bridge = save_exclude; } return; } /* - * mv64x60_exclude_pci_device() + * mv64x60_pci_exclude_device() * * This routine is used to make the bridge not appear when the * PCI subsystem is accessing PCI devices (in PCI config space). */ -static int +int mv64x60_pci_exclude_device(u8 bus, u8 devfn) { struct pci_controller *hose; @@ -2171,41 +1384,63 @@ mv64x60_pci_exclude_device(u8 bus, u8 devfn) hose = pci_bus_to_hose(bus); /* Skip slot 0 on both hoses */ - if ((mv64x60_pci_exclude_bridge == TRUE) && - (PCI_SLOT(devfn) == 0) && - (hose->first_busno == bus)) { + if ((mv64x60_pci_exclude_bridge == 1) && (PCI_SLOT(devfn) == 0) && + (hose->first_busno == bus)) + return PCIBIOS_DEVICE_NOT_FOUND; - } - else { + else return PCIBIOS_SUCCESSFUL; - } } /* mv64x60_pci_exclude_device() */ /* ***************************************************************************** * - * OCP Fixup Routines + * Platform Device Routines * ***************************************************************************** */ + /* - * mv64x60_fixup_ocp() + * mv64x60_pd_fixup() * - * Adjust the 'paddr' field in the bridge's OCP entries to reflect where they - * really are in the physical address space. + * Need to add the base addr of where the bridge's regs are mapped in the + * physical addr space so drivers can ioremap() them. */ -static void __init -mv64x60_fixup_ocp(struct ocp_device *dev, void *arg) +void __init +mv64x60_pd_fixup(struct mv64x60_handle *bh, struct platform_device *pd_devs[], + u32 entries) { - mv64x60_handle_t *bh = (mv64x60_handle_t *)arg; + struct resource *r; + u32 i, j; + + for (i=0; idef->vendor == OCP_VENDOR_MARVELL) { - dev->def->paddr += bh->p_base; + while ((r = platform_get_resource(pd_devs[i],IORESOURCE_MEM,j)) + != NULL) { + + r->start += bh->p_base; + r->end += bh->p_base; + j++; + } } return; } +/* + * mv64x60_add_pds() + * + * Add the mv64x60 platform devices to the list of platform devices. + */ +static int __init +mv64x60_add_pds(void) +{ + return platform_add_devices(mv64x60_pd_devs, + ARRAY_SIZE(mv64x60_pd_devs)); +} +arch_initcall(mv64x60_add_pds); + /* ***************************************************************************** * @@ -2232,12 +1467,10 @@ gt64260_translate_size(u32 base, u32 size, u32 num_bits) static u32 __init gt64260_untranslate_size(u32 base, u32 size, u32 num_bits) { - if (size >= base) { + if (size >= base) size = size - base + (1 << (32 - num_bits)); - } - else { + else size = 0; - } return size; } @@ -2248,17 +1481,50 @@ gt64260_untranslate_size(u32 base, u32 size, u32 num_bits) * 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 __init -gt64260_set_pci2mem_window(struct pci_controller *hose, u32 window, u32 base) +gt64260_set_pci2mem_window(struct pci_controller *hose, u32 bus, u32 window, + u32 base) { - u32 reg_addrs[] = { 0x10, 0x14, 0x18, 0x1c }; + u8 save_exclude; - DBG("set pci->mem window: %d, hose: %d, base: 0x%x\n", window, + pr_debug("set pci->mem window: %d, hose: %d, base: 0x%x\n", window, hose->index, base); - early_write_config_dword(hose, hose->first_busno, - PCI_DEVFN(0, 0), reg_addrs[window], - mv64x60_mask(base, 20) | 0x8); + 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; + + return; +} + +/* + * 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 __init +gt64260_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; + return; } @@ -2269,7 +1535,7 @@ gt64260_set_pci2mem_window(struct pci_controller *hose, u32 window, u32 base) * address. */ static u32 __init -gt64260_is_enabled_32bit(mv64x60_handle_t *bh, u32 window) +gt64260_is_enabled_32bit(struct mv64x60_handle *bh, u32 window) { u32 rc = 0; @@ -2278,17 +1544,9 @@ gt64260_is_enabled_32bit(mv64x60_handle_t *bh, u32 window) ((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)))){ + ((1 << gt64260_32bit_windows[window].base_bits) - 1)))) rc = 1; - } - - if (rc) { - DBG("32bit window %d is enabled\n", window); - } - else { - DBG("32bit window %d is disabled\n", window); - } return rc; } @@ -2301,9 +1559,9 @@ gt64260_is_enabled_32bit(mv64x60_handle_t *bh, u32 window) * the time this routine is called, we have nothing to do here. */ static void __init -gt64260_enable_window_32bit(mv64x60_handle_t *bh, u32 window) +gt64260_enable_window_32bit(struct mv64x60_handle *bh, u32 window) { - DBG("enable 32bit window: %d\n", window); + pr_debug("enable 32bit window: %d\n", window); return; } @@ -2314,9 +1572,9 @@ gt64260_enable_window_32bit(mv64x60_handle_t *bh, u32 window) * than its base address. */ static void __init -gt64260_disable_window_32bit(mv64x60_handle_t *bh, u32 window) +gt64260_disable_window_32bit(struct mv64x60_handle *bh, u32 window) { - DBG("disable 32bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n", + 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); @@ -2339,9 +1597,9 @@ gt64260_disable_window_32bit(mv64x60_handle_t *bh, u32 window) * the time this routine is called, we have nothing to do here. */ static void __init -gt64260_enable_window_64bit(mv64x60_handle_t *bh, u32 window) +gt64260_enable_window_64bit(struct mv64x60_handle *bh, u32 window) { - DBG("enable 64bit window: %d\n", window); + pr_debug("enable 64bit window: %d\n", window); return; /* Enabled when window configured (i.e., when top >= base) */ } @@ -2352,9 +1610,9 @@ gt64260_enable_window_64bit(mv64x60_handle_t *bh, u32 window) * than its base address. */ static void __init -gt64260_disable_window_64bit(mv64x60_handle_t *bh, u32 window) +gt64260_disable_window_64bit(struct mv64x60_handle *bh, u32 window) { - DBG("disable 64bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n", + 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); @@ -2379,21 +1637,26 @@ gt64260_disable_window_64bit(mv64x60_handle_t *bh, u32 window) * except for the memory controller windows, of course. */ static void __init -gt64260_disable_all_windows(mv64x60_handle_t *bh, mv64x60_setup_info_t *si) +gt64260_disable_all_windows(struct mv64x60_handle *bh, + struct mv64x60_setup_info *si) { - u32 i; + u32 i, preserve; /* Disable 32bit windows (don't disable cpu->mem windows) */ for (i=MV64x60_CPU2DEV_0_WIN; iwindow_preserve_mask_32 & (1<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; iwindow_preserve_mask_64 & (1< windows */ - mv64x60_set_bits(bh, MV64x60_PCI0_BAR_ENABLE, 0x07ffffff); - mv64x60_set_bits(bh, MV64x60_PCI1_BAR_ENABLE, 0x07ffffff); + 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); return; } @@ -2444,84 +1722,72 @@ gt64260_disable_all_windows(mv64x60_handle_t *bh, mv64x60_setup_info_t *si) * * Implement errata work arounds for the GT64260A. */ -static void -gt64260a_chip_specific_init(mv64x60_handle_t *bh, mv64x60_setup_info_t *si) +static void __init +gt64260a_chip_specific_init(struct mv64x60_handle *bh, + struct mv64x60_setup_info *si) { - struct ocp_device *dev; - mv64x60_ocp_mpsc_data_t *mpsc_dp; - u8 save_exclude; - u32 val; - - /* R#18 */ - /* cpu read buffer to buffer 1 (reg 0x0448) */ - mv64x60_set_bits(bh, GT64260_SDRAM_CONFIG, (1<<26)); - - /* No longer errata so turn on */ - /* Enable pci read/write combine, master write trigger, - * disable slave sync barrier - * readmultiple (reg 0x0c00 and 0x0c80) - */ - if (si->pci_0.enable_bus) { +#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) { + if (si->pci_1.enable_bus) mv64x60_set_bits(bh, MV64x60_PCI1_CMD, ((1<<4) | (1<<5) | (1<<9) | (1<<13))); - } -#if 1 /* XXXX */ /* * Dave Wilhardt found that bit 4 in the PCI Command registers must * be set if you are using cache coherency. - * - * Note: he also said that bit 4 must be on in all PCI devices but - * that has not been implemented yet. */ +#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 = FALSE; - - early_read_config_dword(bh->hose_a, - bh->hose_a->first_busno, - PCI_DEVFN(0,0), - PCI_COMMAND, - &val); - val |= PCI_COMMAND_INVALIDATE; - early_write_config_dword(bh->hose_a, - bh->hose_a->first_busno, - PCI_DEVFN(0,0), - PCI_COMMAND, - val); - - early_read_config_dword(bh->hose_b, - bh->hose_b->first_busno, - PCI_DEVFN(0,0), - PCI_COMMAND, - &val); - val |= PCI_COMMAND_INVALIDATE; - early_write_config_dword(bh->hose_b, - bh->hose_b->first_busno, - PCI_DEVFN(0,0), - PCI_COMMAND, - val); + 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 - if ((dev = ocp_find_device(OCP_VENDOR_MARVELL, OCP_FUNC_MPSC, 0)) - != NULL) { - mpsc_dp = (mv64x60_ocp_mpsc_data_t *)dev->def->additions; - mpsc_dp->mirror_regs = 1; - mpsc_dp->cache_mgmt = 1; - } + /* 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 ((dev = ocp_find_device(OCP_VENDOR_MARVELL, OCP_FUNC_MPSC, 1)) - != NULL) { - mpsc_dp = (mv64x60_ocp_mpsc_data_t *)dev->def->additions; - mpsc_dp->mirror_regs = 1; - mpsc_dp->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 return; } @@ -2531,49 +1797,77 @@ gt64260a_chip_specific_init(mv64x60_handle_t *bh, mv64x60_setup_info_t *si) * * Implement errata work arounds for the GT64260B. */ -static void -gt64260b_chip_specific_init(mv64x60_handle_t *bh, mv64x60_setup_info_t *si) +static void __init +gt64260b_chip_specific_init(struct mv64x60_handle *bh, + struct mv64x60_setup_info *si) { - struct ocp_device *dev; - mv64x60_ocp_mpsc_data_t *mpsc_dp; - - /* R#18 */ - /* cpu read buffer to buffer 1 (reg 0x0448) */ - mv64x60_set_bits(bh, GT64260_SDRAM_CONFIG, (1<<26)); - - /* No longer errata so turn on */ - /* Enable pci read/write combine, master write trigger, - * disable slave sync barrier - * readmultiple (reg 0x0c00 and 0x0c80) - */ - if (si->pci_0.enable_bus) { +#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) { + 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 /* * 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. */ - if ((dev = ocp_find_device(OCP_VENDOR_MARVELL, OCP_FUNC_MPSC, 0)) - != NULL) { - mpsc_dp = (mv64x60_ocp_mpsc_data_t *)dev->def->additions; - mpsc_dp->cache_mgmt = 1; - } + mv64x60_mpsc0_pdata.cache_mgmt = 1; + mv64x60_mpsc1_pdata.cache_mgmt = 1; - if ((dev = ocp_find_device(OCP_VENDOR_MARVELL, OCP_FUNC_MPSC, 1)) - != NULL) { - mpsc_dp = (mv64x60_ocp_mpsc_data_t *)dev->def->additions; - mpsc_dp->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 return; } @@ -2622,26 +1916,64 @@ mv64360_untranslate_size(u32 base_addr, u32 size, u32 num_bits) * 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 __init -mv64360_set_pci2mem_window(struct pci_controller *hose, u32 window, u32 base) +mv64360_set_pci2mem_window(struct pci_controller *hose, u32 bus, u32 window, + u32 base) { - struct { - u32 fcn; - u32 base_hi_bar; - u32 base_lo_bar; - } reg_addrs[] = {{ 0, 0x14, 0x10 }, { 0, 0x1c, 0x18 }, - { 1, 0x14, 0x10 }, { 1, 0x1c, 0x18 }}; - - DBG("set pci->mem window: %d, hose: %d, base: 0x%x\n", window, + u8 save_exclude; + + pr_debug("set pci->mem window: %d, hose: %d, base: 0x%x\n", window, hose->index, base); - early_write_config_dword(hose, hose->first_busno, - PCI_DEVFN(0, reg_addrs[window].fcn), - reg_addrs[window].base_hi_bar, 0); - early_write_config_dword(hose, hose->first_busno, - PCI_DEVFN(0, reg_addrs[window].fcn), - reg_addrs[window].base_lo_bar, - mv64x60_mask(base, 20) | 0xc); + 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; + + return; +} + +/* + * 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 __init +mv64360_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; + return; } @@ -2654,30 +1986,47 @@ mv64360_set_pci2mem_window(struct pci_controller *hose, u32 window, u32 base) * check those so its okay. */ static u32 __init -mv64360_is_enabled_32bit(mv64x60_handle_t *bh, u32 window) +mv64360_is_enabled_32bit(struct mv64x60_handle *bh, u32 window) { - u32 rc = 0; + u32 extra, rc = 0; + + if (((mv64360_32bit_windows[window].base_reg != 0) && + (mv64360_32bit_windows[window].size_reg != 0)) || + (window == MV64x60_CPU2SRAM_WIN)) { - if ((mv64360_32bit_windows[window].base_reg != 0) && - (mv64360_32bit_windows[window].size_reg != 0)) { + extra = mv64360_32bit_windows[window].extra; - if (mv64360_32bit_windows[window].extra & 0x80000000) { + 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 << (mv64360_32bit_windows[window].extra & - 0xff))) != 0; - } - else { - rc = (mv64x60_read(bh, MV64360_CPU_BAR_ENABLE) & - (1 << mv64360_32bit_windows[window].extra)) ==0; - } - } + mv64360_32bit_windows[window].base_reg) & + (1 << (extra & 0x1f))) != 0; + break; - if (rc) { - DBG("32bit window %d is enabled\n", window); - } - else { - DBG("32bit window %d is disabled\n", window); + 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; @@ -2690,22 +2039,48 @@ mv64360_is_enabled_32bit(mv64x60_handle_t *bh, u32 window) * CPU BAR Enable reg or setting a bit in the window's base reg. */ static void __init -mv64360_enable_window_32bit(mv64x60_handle_t *bh, u32 window) +mv64360_enable_window_32bit(struct mv64x60_handle *bh, u32 window) { - DBG("enable 32bit window: %d\n", 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; - if ((mv64360_32bit_windows[window].base_reg != 0) && - (mv64360_32bit_windows[window].size_reg != 0)) { + switch (extra & MV64x60_EXTRA_MASK) { + case MV64x60_EXTRA_CPUWIN_ENAB: + mv64x60_clr_bits(bh, MV64360_CPU_BAR_ENABLE, + (1 << (extra & 0x1f))); + break; - if (mv64360_32bit_windows[window].extra & 0x80000000) { + case MV64x60_EXTRA_CPUPROT_ENAB: mv64x60_set_bits(bh, mv64360_32bit_windows[window].base_reg, - (1 << (mv64360_32bit_windows[window].extra & - 0xff))); - } - else { - mv64x60_clr_bits(bh, MV64360_CPU_BAR_ENABLE, - (1 << mv64360_32bit_windows[window].extra)); + (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"); } } @@ -2719,24 +2094,50 @@ mv64360_enable_window_32bit(mv64x60_handle_t *bh, u32 window) * CPU BAR Enable reg or clearing a bit in the window's base reg. */ static void __init -mv64360_disable_window_32bit(mv64x60_handle_t *bh, u32 window) +mv64360_disable_window_32bit(struct mv64x60_handle *bh, u32 window) { - DBG("disable 32bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n", + 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)) { + 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; - if (mv64360_32bit_windows[window].extra & 0x80000000) { + 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 << (mv64360_32bit_windows[window].extra & - 0xff))); - } - else { - mv64x60_set_bits(bh, MV64360_CPU_BAR_ENABLE, - (1 << mv64360_32bit_windows[window].extra)); + (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"); } } @@ -2746,24 +2147,27 @@ mv64360_disable_window_32bit(mv64x60_handle_t *bh, u32 window) /* * mv64360_enable_window_64bit() * - * On the MV64360, a 64-bit window is enabled by setting a bit in the window's + * On the MV64360, a 64-bit window is enabled by setting a bit in the window's * base reg. */ static void __init -mv64360_enable_window_64bit(mv64x60_handle_t *bh, u32 window) +mv64360_enable_window_64bit(struct mv64x60_handle *bh, u32 window) { - DBG("enable 64bit window: %d\n", window); + pr_debug("enable 64bit window: %d\n", window); - /* For 64360, 'extra' field holds bit that enables the window */ if ((mv64360_64bit_windows[window].base_lo_reg!= 0) && (mv64360_64bit_windows[window].size_reg != 0)) { - if (mv64360_64bit_windows[window].extra & 0x80000000) { + 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 & - 0xff))); - } /* Should be no 'else' ones */ + 0x1f))); + else + printk(KERN_ERR "mv64360_enable: %s\n", + "64bit table corrupted"); } return; @@ -2776,21 +2180,25 @@ mv64360_enable_window_64bit(mv64x60_handle_t *bh, u32 window) * base reg. */ static void __init -mv64360_disable_window_64bit(mv64x60_handle_t *bh, u32 window) +mv64360_disable_window_64bit(struct mv64x60_handle *bh, u32 window) { - DBG("disable 64bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n", + 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 & 0x80000000) { + 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 & - 0xff))); - } /* Should be no 'else' ones */ + 0x1f))); + else + printk(KERN_ERR "mv64360_disable: %s\n", + "64bit table corrupted"); } return; @@ -2804,21 +2212,26 @@ mv64360_disable_window_64bit(mv64x60_handle_t *bh, u32 window) * except for the memory controller windows, of course. */ static void __init -mv64360_disable_all_windows(mv64x60_handle_t *bh, mv64x60_setup_info_t *si) +mv64360_disable_all_windows(struct mv64x60_handle *bh, + struct mv64x60_setup_info *si) { - u32 i; + u32 preserve, i; /* Disable 32bit windows (don't disable cpu->mem windows) */ for (i=MV64x60_CPU2DEV_0_WIN; iwindow_preserve_mask_32 & (1<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; iwindow_preserve_mask_64 & (1<MEM access cntl wins not in mv64360_64bit_windows[] */ mv64x60_clr_bits(bh, MV64x60_PCI0_ACC_CNTL_4_BASE_LO, 0); @@ -2834,27 +2247,130 @@ mv64360_disable_all_windows(mv64x60_handle_t *bh, mv64x60_setup_info_t *si) } /* - * mv64360_chip_specific_init() + * mv64360_config_io2mem_windows() * - * No errata work arounds for the MV64360 implemented at this point. + * 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 void -mv64360_chip_specific_init(mv64x60_handle_t *bh, mv64x60_setup_info_t *si) +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 __init +mv64360_config_io2mem_windows(struct mv64x60_handle *bh, + struct mv64x60_setup_info *si, + u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]) { - struct ocp_device *dev; - mv64x60_ocp_mpsc_data_t *mpsc_dp; + u32 i, win; - if ((dev = ocp_find_device(OCP_VENDOR_MARVELL, OCP_FUNC_MPSC, 0)) - != NULL) { - mpsc_dp = (mv64x60_ocp_mpsc_data_t *)dev->def->additions; - mpsc_dp->brg_can_tune = 1; - } + pr_debug("config_io2regs_windows: enet, mpsc, idma -> bridge regs\n"); - if ((dev = ocp_find_device(OCP_VENDOR_MARVELL, OCP_FUNC_MPSC, 1)) - != NULL) { - mpsc_dp = (mv64x60_ocp_mpsc_data_t *)dev->def->additions; - mpsc_dp->brg_can_tune = 1; - } + 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))); + mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_1, + (0x3 << (i << 1))); + mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_2, + (0x3 << (i << 1))); + mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_3, + (0x3 << (i << 1))); + } + + return; +} + +/* + * mv64360_set_mpsc2regs_window() + * + * MPSC has a window to the bridge's internal registers. Call this routine + * to change that window so it doesn't conflict with the windows mapping the + * mpsc to system memory. + */ +static void __init +mv64360_set_mpsc2regs_window(struct mv64x60_handle *bh, u32 base) +{ + pr_debug("set mpsc->internal regs, base: 0x%x\n", base); + + mv64x60_write(bh, MV64360_MPSC2REGS_BASE, base & 0xffff0000); + return; +} + +/* + * mv64360_chip_specific_init() + * + * No errata work arounds for the MV64360 implemented at this point. + */ +static void __init +mv64360_chip_specific_init(struct mv64x60_handle *bh, + struct mv64x60_setup_info *si) +{ +#ifdef CONFIG_SERIAL_MPSC + mv64x60_mpsc0_pdata.brg_can_tune = 1; + mv64x60_mpsc0_pdata.cache_mgmt = 1; + mv64x60_mpsc1_pdata.brg_can_tune = 1; + mv64x60_mpsc1_pdata.cache_mgmt = 1; +#endif return; } @@ -2864,9 +2380,13 @@ mv64360_chip_specific_init(mv64x60_handle_t *bh, mv64x60_setup_info_t *si) * * No errata work arounds for the MV64460 implemented at this point. */ -static void -mv64460_chip_specific_init(mv64x60_handle_t *bh, mv64x60_setup_info_t *si) +static void __init +mv64460_chip_specific_init(struct mv64x60_handle *bh, + struct mv64x60_setup_info *si) { - mv64360_chip_specific_init(bh, si); /* XXXX check errata */ +#ifdef CONFIG_SERIAL_MPSC + mv64x60_mpsc0_pdata.brg_can_tune = 1; + mv64x60_mpsc1_pdata.brg_can_tune = 1; +#endif return; }