Index: head/sys/arm/mv/armada38x/armada38x.c =================================================================== --- head/sys/arm/mv/armada38x/armada38x.c (revision 294437) +++ head/sys/arm/mv/armada38x/armada38x.c (revision 294438) @@ -1,103 +1,137 @@ /*- * Copyright (c) 2015 Semihalf. * Copyright (c) 2015 Stormshield. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include -int armada38x_win_set_iosync_barrier(void); +int armada38x_open_bootrom_win(void); int armada38x_scu_enable(void); +int armada38x_win_set_iosync_barrier(void); uint32_t get_tclk(void) { uint32_t sar; /* * On Armada38x TCLK can be configured to 250 MHz or 200 MHz. * Current setting is read from Sample At Reset register. */ sar = (uint32_t)get_sar_value(); sar = (sar & TCLK_MASK) >> TCLK_SHIFT; if (sar == 0) return (TCLK_250MHZ); else return (TCLK_200MHZ); } int armada38x_win_set_iosync_barrier(void) { bus_space_handle_t vaddr_iowind; int rv; rv = bus_space_map(fdtbus_bs_tag, (bus_addr_t)MV_MBUS_BRIDGE_BASE, MV_CPU_SUBSYS_REGS_LEN, 0, &vaddr_iowind); if (rv != 0) return (rv); /* Set Sync Barrier flags for all Mbus internal units */ bus_space_write_4(fdtbus_bs_tag, vaddr_iowind, MV_SYNC_BARRIER_CTRL, MV_SYNC_BARRIER_CTRL_ALL); bus_space_barrier(fdtbus_bs_tag, vaddr_iowind, 0, MV_CPU_SUBSYS_REGS_LEN, BUS_SPACE_BARRIER_WRITE); + bus_space_unmap(fdtbus_bs_tag, vaddr_iowind, MV_CPU_SUBSYS_REGS_LEN); + + return (rv); +} + +int +armada38x_open_bootrom_win(void) +{ + bus_space_handle_t vaddr_iowind; + uint32_t val; + int rv; + + rv = bus_space_map(fdtbus_bs_tag, (bus_addr_t)MV_MBUS_BRIDGE_BASE, + MV_CPU_SUBSYS_REGS_LEN, 0, &vaddr_iowind); + if (rv != 0) + return (rv); + + val = (MV_BOOTROM_WIN_SIZE & IO_WIN_SIZE_MASK) << IO_WIN_SIZE_SHIFT; + val |= (MBUS_BOOTROM_ATTR & IO_WIN_ATTR_MASK) << IO_WIN_ATTR_SHIFT; + val |= (MBUS_BOOTROM_TGT_ID & IO_WIN_TGT_MASK) << IO_WIN_TGT_SHIFT; + /* Enable window and Sync Barrier */ + val |= (0x1 & IO_WIN_SYNC_MASK) << IO_WIN_SYNC_SHIFT; + val |= (0x1 & IO_WIN_ENA_MASK) << IO_WIN_ENA_SHIFT; + + /* Configure IO Window Control Register */ + bus_space_write_4(fdtbus_bs_tag, vaddr_iowind, IO_WIN_9_CTRL_OFFSET, + val); + /* Configure IO Window Base Register */ + bus_space_write_4(fdtbus_bs_tag, vaddr_iowind, IO_WIN_9_BASE_OFFSET, + MV_BOOTROM_MEM_ADDR); + + bus_space_barrier(fdtbus_bs_tag, vaddr_iowind, 0, MV_CPU_SUBSYS_REGS_LEN, + BUS_SPACE_BARRIER_WRITE); bus_space_unmap(fdtbus_bs_tag, vaddr_iowind, MV_CPU_SUBSYS_REGS_LEN); return (rv); } int armada38x_scu_enable(void) { bus_space_handle_t vaddr_scu; int rv; uint32_t val; rv = bus_space_map(fdtbus_bs_tag, (bus_addr_t)MV_SCU_BASE, MV_SCU_REGS_LEN, 0, &vaddr_scu); if (rv != 0) return (rv); /* Enable SCU */ val = bus_space_read_4(fdtbus_bs_tag, vaddr_scu, MV_SCU_REG_CTRL); if (!(val & MV_SCU_ENABLE)) bus_space_write_4(fdtbus_bs_tag, vaddr_scu, 0, val | MV_SCU_ENABLE); bus_space_unmap(fdtbus_bs_tag, vaddr_scu, MV_SCU_REGS_LEN); return (0); } Index: head/sys/arm/mv/mv_machdep.c =================================================================== --- head/sys/arm/mv/mv_machdep.c (revision 294437) +++ head/sys/arm/mv/mv_machdep.c (revision 294438) @@ -1,498 +1,504 @@ /*- * Copyright (c) 1994-1998 Mark Brinicombe. * Copyright (c) 1994 Brini. * All rights reserved. * * This code is derived from software written for Brini by Mark Brinicombe * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Brini. * 4. The name of the company nor the name of the author may be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: FreeBSD: //depot/projects/arm/src/sys/arm/at91/kb920x_machdep.c, rev 45 */ #include "opt_ddb.h" #include "opt_platform.h" #include __FBSDID("$FreeBSD$"); #define _ARM32_BUS_DMA_PRIVATE #include #include #include #include #include #include #include #include #include #include #include /* XXX */ #include /* XXX eventually this should be eliminated */ #include #include static int platform_mpp_init(void); #if defined(SOC_MV_ARMADAXP) void armadaxp_init_coher_fabric(void); void armadaxp_l2_init(void); #endif #if defined(SOC_MV_ARMADA38X) int armada38x_win_set_iosync_barrier(void); int armada38x_scu_enable(void); +int armada38x_open_bootrom_win(void); #endif #define MPP_PIN_MAX 68 #define MPP_PIN_CELLS 2 #define MPP_PINS_PER_REG 8 #define MPP_SEL(pin,func) (((func) & 0xf) << \ (((pin) % MPP_PINS_PER_REG) * 4)) static int platform_mpp_init(void) { pcell_t pinmap[MPP_PIN_MAX * MPP_PIN_CELLS]; int mpp[MPP_PIN_MAX]; uint32_t ctrl_val, ctrl_offset; pcell_t reg[4]; u_long start, size; phandle_t node; pcell_t pin_cells, *pinmap_ptr, pin_count; ssize_t len; int par_addr_cells, par_size_cells; int tuple_size, tuples, rv, pins, i, j; int mpp_pin, mpp_function; /* * Try to access the MPP node directly i.e. through /aliases/mpp. */ if ((node = OF_finddevice("mpp")) != -1) if (fdt_is_compatible(node, "mrvl,mpp")) goto moveon; /* * Find the node the long way. */ if ((node = OF_finddevice("/")) == -1) return (ENXIO); if ((node = fdt_find_compatible(node, "simple-bus", 0)) == 0) return (ENXIO); if ((node = fdt_find_compatible(node, "mrvl,mpp", 0)) == 0) /* * No MPP node. Fall back to how MPP got set by the * first-stage loader and try to continue booting. */ return (0); moveon: /* * Process 'reg' prop. */ if ((rv = fdt_addrsize_cells(OF_parent(node), &par_addr_cells, &par_size_cells)) != 0) return(ENXIO); tuple_size = sizeof(pcell_t) * (par_addr_cells + par_size_cells); len = OF_getprop(node, "reg", reg, sizeof(reg)); tuples = len / tuple_size; if (tuple_size <= 0) return (EINVAL); /* * Get address/size. XXX we assume only the first 'reg' tuple is used. */ rv = fdt_data_to_res(reg, par_addr_cells, par_size_cells, &start, &size); if (rv != 0) return (rv); start += fdt_immr_va; /* * Process 'pin-count' and 'pin-map' props. */ if (OF_getprop(node, "pin-count", &pin_count, sizeof(pin_count)) <= 0) return (ENXIO); pin_count = fdt32_to_cpu(pin_count); if (pin_count > MPP_PIN_MAX) return (ERANGE); if (OF_getprop(node, "#pin-cells", &pin_cells, sizeof(pin_cells)) <= 0) pin_cells = MPP_PIN_CELLS; pin_cells = fdt32_to_cpu(pin_cells); if (pin_cells > MPP_PIN_CELLS) return (ERANGE); tuple_size = sizeof(pcell_t) * pin_cells; bzero(pinmap, sizeof(pinmap)); len = OF_getprop(node, "pin-map", pinmap, sizeof(pinmap)); if (len <= 0) return (ERANGE); if (len % tuple_size) return (ERANGE); pins = len / tuple_size; if (pins > pin_count) return (ERANGE); /* * Fill out a "mpp[pin] => function" table. All pins unspecified in * the 'pin-map' property are defaulted to 0 function i.e. GPIO. */ bzero(mpp, sizeof(mpp)); pinmap_ptr = pinmap; for (i = 0; i < pins; i++) { mpp_pin = fdt32_to_cpu(*pinmap_ptr); mpp_function = fdt32_to_cpu(*(pinmap_ptr + 1)); mpp[mpp_pin] = mpp_function; pinmap_ptr += pin_cells; } /* * Prepare and program MPP control register values. */ ctrl_offset = 0; for (i = 0; i < pin_count;) { ctrl_val = 0; for (j = 0; j < MPP_PINS_PER_REG; j++) { if (i + j == pin_count - 1) break; ctrl_val |= MPP_SEL(i + j, mpp[i + j]); } i += MPP_PINS_PER_REG; bus_space_write_4(fdtbus_bs_tag, start, ctrl_offset, ctrl_val); #if defined(SOC_MV_ORION) /* * Third MPP reg on Orion SoC is placed * non-linearly (with different offset). */ if (i == (2 * MPP_PINS_PER_REG)) ctrl_offset = 0x50; else #endif ctrl_offset += 4; } return (0); } vm_offset_t platform_lastaddr(void) { return (fdt_immr_va); } void platform_probe_and_attach(void) { if (fdt_immr_addr(MV_BASE) != 0) while (1); } void platform_gpio_init(void) { /* * Re-initialise MPP. It is important to call this prior to using * console as the physical connection can be routed via MPP. */ if (platform_mpp_init() != 0) while (1); } void platform_late_init(void) { /* * Re-initialise decode windows */ #if !defined(SOC_MV_FREY) if (soc_decode_win() != 0) printf("WARNING: could not re-initialise decode windows! " "Running with existing settings...\n"); #else /* Disable watchdog and timers */ write_cpu_ctrl(CPU_TIMERS_BASE + CPU_TIMER_CONTROL, 0); #endif #if defined(SOC_MV_ARMADAXP) #if !defined(SMP) /* For SMP case it should be initialized after APs are booted */ armadaxp_init_coher_fabric(); #endif armadaxp_l2_init(); #endif #if defined(SOC_MV_ARMADA38X) /* Set IO Sync Barrier bit for all Mbus devices */ if (armada38x_win_set_iosync_barrier() != 0) printf("WARNING: could not map CPU Subsystem registers\n"); if (armada38x_scu_enable() != 0) printf("WARNING: could not enable SCU\n"); +#ifdef SMP + /* Open window to bootROM memory - needed for SMP */ + if (armada38x_open_bootrom_win() != 0) + printf("WARNING: could not open window to bootROM\n"); +#endif #endif } #define FDT_DEVMAP_MAX (MV_WIN_CPU_MAX + 2) static struct arm_devmap_entry fdt_devmap[FDT_DEVMAP_MAX] = { { 0, 0, 0, 0, 0, } }; static int platform_sram_devmap(struct arm_devmap_entry *map) { #if !defined(SOC_MV_ARMADAXP) phandle_t child, root; u_long base, size; /* * SRAM range. */ if ((child = OF_finddevice("/sram")) != 0) if (fdt_is_compatible(child, "mrvl,cesa-sram") || fdt_is_compatible(child, "mrvl,scratchpad")) goto moveon; if ((root = OF_finddevice("/")) == 0) return (ENXIO); if ((child = fdt_find_compatible(root, "mrvl,cesa-sram", 0)) == 0 && (child = fdt_find_compatible(root, "mrvl,scratchpad", 0)) == 0) goto out; moveon: if (fdt_regsize(child, &base, &size) != 0) return (EINVAL); map->pd_va = MV_CESA_SRAM_BASE; /* XXX */ map->pd_pa = base; map->pd_size = size; map->pd_prot = VM_PROT_READ | VM_PROT_WRITE; map->pd_cache = PTE_DEVICE; return (0); out: #endif return (ENOENT); } /* * Supply a default do-nothing implementation of mv_pci_devmap() via a weak * alias. Many Marvell platforms don't support a PCI interface, but to support * those that do, we end up with a reference to this function below, in * platform_devmap_init(). If "device pci" appears in the kernel config, the * real implementation of this function in arm/mv/mv_pci.c overrides the weak * alias defined here. */ int mv_default_fdt_pci_devmap(phandle_t node, struct arm_devmap_entry *devmap, vm_offset_t io_va, vm_offset_t mem_va); int mv_default_fdt_pci_devmap(phandle_t node, struct arm_devmap_entry *devmap, vm_offset_t io_va, vm_offset_t mem_va) { return (0); } __weak_reference(mv_default_fdt_pci_devmap, mv_pci_devmap); /* * XXX: When device entry in devmap has pd_size smaller than section size, * system will freeze during initialization */ /* * Construct pmap_devmap[] with DT-derived config data. */ int platform_devmap_init(void) { phandle_t root, child; pcell_t bank_count; int i, num_mapped; i = 0; arm_devmap_register_table(&fdt_devmap[0]); #ifdef SOC_MV_ARMADAXP vm_paddr_t cur_immr_pa; /* * Acquire SoC registers' base passed by u-boot and fill devmap * accordingly. DTB is going to be modified basing on this data * later. */ __asm __volatile("mrc p15, 4, %0, c15, c0, 0" : "=r" (cur_immr_pa)); cur_immr_pa = (cur_immr_pa << 13) & 0xff000000; if (cur_immr_pa != 0) fdt_immr_pa = cur_immr_pa; #endif /* * IMMR range. */ fdt_devmap[i].pd_va = fdt_immr_va; fdt_devmap[i].pd_pa = fdt_immr_pa; fdt_devmap[i].pd_size = fdt_immr_size; fdt_devmap[i].pd_prot = VM_PROT_READ | VM_PROT_WRITE; fdt_devmap[i].pd_cache = PTE_DEVICE; i++; /* * SRAM range. */ if (i < FDT_DEVMAP_MAX) if (platform_sram_devmap(&fdt_devmap[i]) == 0) i++; /* * PCI range(s). * PCI range(s) and localbus. */ if ((root = OF_finddevice("/")) == -1) return (ENXIO); for (child = OF_child(root); child != 0; child = OF_peer(child)) { if (fdt_is_type(child, "pci") || fdt_is_type(child, "pciep")) { /* * Check space: each PCI node will consume 2 devmap * entries. */ if (i + 1 >= FDT_DEVMAP_MAX) return (ENOMEM); /* * XXX this should account for PCI and multiple ranges * of a given kind. */ if (mv_pci_devmap(child, &fdt_devmap[i], MV_PCI_VA_IO_BASE, MV_PCI_VA_MEM_BASE) != 0) return (ENXIO); i += 2; } if (fdt_is_compatible(child, "mrvl,lbc")) { /* Check available space */ if (OF_getprop(child, "bank-count", (void *)&bank_count, sizeof(bank_count)) <= 0) /* If no property, use default value */ bank_count = 1; else bank_count = fdt32_to_cpu(bank_count); if ((i + bank_count) >= FDT_DEVMAP_MAX) return (ENOMEM); /* Add all localbus ranges to device map */ num_mapped = 0; if (fdt_localbus_devmap(child, &fdt_devmap[i], (int)bank_count, &num_mapped) != 0) return (ENXIO); i += num_mapped; } } return (0); } struct arm32_dma_range * bus_dma_get_range(void) { return (NULL); } int bus_dma_get_range_nb(void) { return (0); } #if defined(CPU_MV_PJ4B) #ifdef DDB #include DB_SHOW_COMMAND(cp15, db_show_cp15) { u_int reg; __asm __volatile("mrc p15, 0, %0, c0, c0, 0" : "=r" (reg)); db_printf("Cpu ID: 0x%08x\n", reg); __asm __volatile("mrc p15, 0, %0, c0, c0, 1" : "=r" (reg)); db_printf("Current Cache Lvl ID: 0x%08x\n",reg); __asm __volatile("mrc p15, 0, %0, c1, c0, 0" : "=r" (reg)); db_printf("Ctrl: 0x%08x\n",reg); __asm __volatile("mrc p15, 0, %0, c1, c0, 1" : "=r" (reg)); db_printf("Aux Ctrl: 0x%08x\n",reg); __asm __volatile("mrc p15, 0, %0, c0, c1, 0" : "=r" (reg)); db_printf("Processor Feat 0: 0x%08x\n", reg); __asm __volatile("mrc p15, 0, %0, c0, c1, 1" : "=r" (reg)); db_printf("Processor Feat 1: 0x%08x\n", reg); __asm __volatile("mrc p15, 0, %0, c0, c1, 2" : "=r" (reg)); db_printf("Debug Feat 0: 0x%08x\n", reg); __asm __volatile("mrc p15, 0, %0, c0, c1, 3" : "=r" (reg)); db_printf("Auxiliary Feat 0: 0x%08x\n", reg); __asm __volatile("mrc p15, 0, %0, c0, c1, 4" : "=r" (reg)); db_printf("Memory Model Feat 0: 0x%08x\n", reg); __asm __volatile("mrc p15, 0, %0, c0, c1, 5" : "=r" (reg)); db_printf("Memory Model Feat 1: 0x%08x\n", reg); __asm __volatile("mrc p15, 0, %0, c0, c1, 6" : "=r" (reg)); db_printf("Memory Model Feat 2: 0x%08x\n", reg); __asm __volatile("mrc p15, 0, %0, c0, c1, 7" : "=r" (reg)); db_printf("Memory Model Feat 3: 0x%08x\n", reg); __asm __volatile("mrc p15, 1, %0, c15, c2, 0" : "=r" (reg)); db_printf("Aux Func Modes Ctrl 0: 0x%08x\n",reg); __asm __volatile("mrc p15, 1, %0, c15, c2, 1" : "=r" (reg)); db_printf("Aux Func Modes Ctrl 1: 0x%08x\n",reg); __asm __volatile("mrc p15, 1, %0, c15, c12, 0" : "=r" (reg)); db_printf("CPU ID code extension: 0x%08x\n",reg); } DB_SHOW_COMMAND(vtop, db_show_vtop) { u_int reg; if (have_addr) { __asm __volatile("mcr p15, 0, %0, c7, c8, 0" : : "r" (addr)); __asm __volatile("mrc p15, 0, %0, c7, c4, 0" : "=r" (reg)); db_printf("Physical address reg: 0x%08x\n",reg); } else db_printf("show vtop \n"); } #endif /* DDB */ #endif /* CPU_MV_PJ4B */ Index: head/sys/arm/mv/mvwin.h =================================================================== --- head/sys/arm/mv/mvwin.h (revision 294437) +++ head/sys/arm/mv/mvwin.h (revision 294438) @@ -1,408 +1,427 @@ /*- * Copyright (C) 2007-2011 MARVELL INTERNATIONAL LTD. * All rights reserved. * * Developed by Semihalf. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of MARVELL nor the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _MVWIN_H_ #define _MVWIN_H_ /* * Decode windows addresses. * * All decoding windows must be aligned to their size, which has to be * a power of 2. */ /* * SoC Integrated devices: 0xF1000000, 16 MB (VA == PA) */ /* SoC Regs */ #define MV_PHYS_BASE 0xF1000000 #define MV_SIZE (1024 * 1024) /* 1 MB */ /* SRAM */ #define MV_CESA_SRAM_BASE 0xF1100000 /* AXI Regs */ #ifdef SOC_MV_DOVE #define MV_AXI_PHYS_BASE 0xF1800000 #define MV_AXI_BASE MV_AXI_PHYS_BASE #define MV_AXI_SIZE (16 * 1024 * 1024) /* 16 MB */ #endif /* * External devices: 0x80000000, 1 GB (VA == PA) * Includes Device Bus, PCI and PCIE. */ #if defined(SOC_MV_ORION) #define MV_PCI_PORTS 2 /* 1x PCI + 1x PCIE */ #elif defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_FREY) #define MV_PCI_PORTS 1 /* 1x PCIE */ #elif defined(SOC_MV_DISCOVERY) #define MV_PCI_PORTS 8 /* 8x PCIE */ #elif defined(SOC_MV_DOVE) || defined(SOC_MV_LOKIPLUS) #define MV_PCI_PORTS 2 /* 2x PCIE */ #elif defined(SOC_MV_ARMADAXP) #define MV_PCI_PORTS 3 /* 3x PCIE */ #elif defined(SOC_MV_ARMADA38X) #define MV_PCI_PORTS 4 /* 4x PCIE */ #else #error "MV_PCI_PORTS not configured !" #endif /* PCI/PCIE Memory */ #define MV_PCI_MEM_PHYS_BASE 0x80000000 #define MV_PCI_MEM_SIZE (512 * 1024 * 1024) /* 512 MB */ #define MV_PCI_MEM_BASE MV_PCI_MEM_PHYS_BASE #define MV_PCI_MEM_SLICE_SIZE (MV_PCI_MEM_SIZE / MV_PCI_PORTS) #define MV_PCI_MEM_SLICE(n) (MV_PCI_MEM_BASE + ((n) * \ MV_PCI_MEM_SLICE_SIZE)) /* PCI/PCIE I/O */ #define MV_PCI_IO_PHYS_BASE 0xBF000000 #define MV_PCI_IO_SIZE (16 * 1024 * 1024) /* 16 MB */ #define MV_PCI_IO_BASE MV_PCI_IO_PHYS_BASE #define MV_PCI_IO_SLICE_SIZE (MV_PCI_IO_SIZE / MV_PCI_PORTS) #define MV_PCI_IO_SLICE(n) (MV_PCI_IO_BASE + ((n) * MV_PCI_IO_SLICE_SIZE)) #if defined(SOC_MV_FREY) #define MV_PCI_VA_MEM_BASE MV_PCI_MEM_BASE #else #define MV_PCI_VA_MEM_BASE 0 #endif #define MV_PCI_VA_IO_BASE 0 /* * Device Bus (VA == PA) */ #define MV_DEV_BOOT_BASE 0xF9300000 #define MV_DEV_BOOT_SIZE (1024 * 1024) /* 1 MB */ #define MV_DEV_CS0_BASE 0xF9400000 #define MV_DEV_CS0_SIZE (1024 * 1024) /* 1 MB */ #define MV_DEV_CS1_BASE 0xF9500000 #define MV_DEV_CS1_SIZE (32 * 1024 * 1024) /* 32 MB */ #define MV_DEV_CS2_BASE 0xFB500000 #define MV_DEV_CS2_SIZE (1024 * 1024) /* 1 MB */ /* * Integrated SoC peripherals addresses */ #define MV_BASE MV_PHYS_BASE /* VA == PA mapping */ #if defined(SOC_MV_DOVE) #define MV_DDR_CADR_BASE (MV_AXI_BASE + 0x100) #elif defined(SOC_MV_LOKIPLUS) #define MV_DDR_CADR_BASE (MV_BASE + 0xF1500) #elif defined(SOC_MV_ARMADAXP) || defined(SOC_MV_ARMADA38X) #define MV_DDR_CADR_BASE (MV_BASE + 0x20180) #else #define MV_DDR_CADR_BASE (MV_BASE + 0x1500) #endif #define MV_MPP_BASE (MV_BASE + 0x10000) #if defined(SOC_MV_ARMADAXP) || defined(SOC_MV_ARMADA38X) #define MV_MISC_BASE (MV_BASE + 0x18200) #define MV_MBUS_BRIDGE_BASE (MV_BASE + 0x20000) #define MV_INTREGS_BASE (MV_MBUS_BRIDGE_BASE + 0x80) #define MV_MP_CLOCKS_BASE (MV_MBUS_BRIDGE_BASE + 0x700) #define MV_CPU_CONTROL_BASE (MV_MBUS_BRIDGE_BASE + 0x1800) #elif !defined(SOC_MV_FREY) #define MV_MBUS_BRIDGE_BASE (MV_BASE + 0x20000) #define MV_INTREGS_BASE (MV_MBUS_BRIDGE_BASE + 0x80) #define MV_CPU_CONTROL_BASE (MV_MBUS_BRIDGE_BASE + 0x100) #else #define MV_CPU_CONTROL_BASE (MV_BASE + 0x10000) #endif #define MV_PCI_BASE (MV_BASE + 0x30000) #define MV_PCI_SIZE 0x2000 #if defined(SOC_MV_FREY) #define MV_PCIE_BASE (MV_BASE + 0x8000) #elif defined(SOC_MV_ARMADA38X) #define MV_PCIE_BASE (MV_BASE + 0x80000) #else #define MV_PCIE_BASE (MV_BASE + 0x40000) #endif #define MV_PCIE_SIZE 0x2000 #define MV_PCIE00_BASE (MV_PCIE_BASE + 0x00000) #define MV_PCIE01_BASE (MV_PCIE_BASE + 0x04000) #define MV_PCIE02_BASE (MV_PCIE_BASE + 0x08000) #define MV_PCIE03_BASE (MV_PCIE_BASE + 0x0C000) #define MV_PCIE10_BASE (MV_PCIE_BASE + 0x40000) #define MV_PCIE11_BASE (MV_PCIE_BASE + 0x44000) #define MV_PCIE12_BASE (MV_PCIE_BASE + 0x48000) #define MV_PCIE13_BASE (MV_PCIE_BASE + 0x4C000) #define MV_SDIO_BASE (MV_BASE + 0x90000) #define MV_SDIO_SIZE 0x10000 /* * Decode windows definitions and macros */ #if defined(SOC_MV_ARMADAXP) || defined(SOC_MV_ARMADA38X) #define MV_WIN_CPU_CTRL(n) (((n) < 8) ? 0x10 * (n) : 0x90 + (0x8 * ((n) - 8))) #define MV_WIN_CPU_BASE(n) ((((n) < 8) ? 0x10 * (n) : 0x90 + (0x8 * ((n) - 8))) + 0x4) #define MV_WIN_CPU_REMAP_LO(n) (0x10 * (n) + 0x008) #define MV_WIN_CPU_REMAP_HI(n) (0x10 * (n) + 0x00C) #else #define MV_WIN_CPU_CTRL(n) (0x10 * (n) + (((n) < 8) ? 0x000 : 0x880)) #define MV_WIN_CPU_BASE(n) (0x10 * (n) + (((n) < 8) ? 0x004 : 0x884)) #define MV_WIN_CPU_REMAP_LO(n) (0x10 * (n) + (((n) < 8) ? 0x008 : 0x888)) #define MV_WIN_CPU_REMAP_HI(n) (0x10 * (n) + (((n) < 8) ? 0x00C : 0x88C)) #endif #if defined(SOC_MV_DISCOVERY) #define MV_WIN_CPU_MAX 14 #elif defined(SOC_MV_ARMADAXP) || defined(SOC_MV_ARMADA38X) #define MV_WIN_CPU_MAX 20 #else #define MV_WIN_CPU_MAX 8 #endif #define MV_WIN_CPU_ATTR_SHIFT 8 #if defined(SOC_MV_LOKIPLUS) #define MV_WIN_CPU_TARGET_SHIFT 0 #define MV_WIN_CPU_ENABLE_BIT (1 << 5) #else #define MV_WIN_CPU_TARGET_SHIFT 4 #define MV_WIN_CPU_ENABLE_BIT 1 #endif #if defined(SOC_MV_DOVE) #define MV_WIN_DDR_MAX 2 #else /* SOC_MV_DOVE */ #if defined(SOC_MV_LOKIPLUS) #define MV_WIN_DDR_BASE(n) (0xc * (n) + 0x4) #define MV_WIN_DDR_SIZE(n) (0xc * (n) + 0x0) #else /* SOC_MV_LOKIPLUS */ #define MV_WIN_DDR_BASE(n) (0x8 * (n) + 0x0) #define MV_WIN_DDR_SIZE(n) (0x8 * (n) + 0x4) #endif /* SOC_MV_LOKIPLUS */ #define MV_WIN_DDR_MAX 4 #endif /* SOC_MV_DOVE */ /* * These values are valid only for peripherals decoding windows * Bit in ATTR is zeroed according to CS bank number */ #define MV_WIN_DDR_ATTR(cs) (0x0F & ~(0x01 << (cs))) #define MV_WIN_DDR_TARGET 0x0 #if defined(SOC_MV_DISCOVERY) #define MV_WIN_CESA_TARGET 9 #define MV_WIN_CESA_ATTR(eng_sel) 1 #elif defined(SOC_MV_ARMADAXP) #define MV_WIN_CESA_TARGET 9 /* * Bits [2:3] of cesa attribute select engine: * eng_sel: * 1: engine1 * 2: engine0 */ #define MV_WIN_CESA_ATTR(eng_sel) (1 | ((eng_sel) << 2)) #else #define MV_WIN_CESA_TARGET 3 #define MV_WIN_CESA_ATTR(eng_sel) 0 #endif #define MV_WIN_USB_CTRL(n) (0x10 * (n) + 0x320) #define MV_WIN_USB_BASE(n) (0x10 * (n) + 0x324) #define MV_WIN_USB_MAX 4 #define MV_WIN_ETH_BASE(n) (0x8 * (n) + 0x200) #define MV_WIN_ETH_SIZE(n) (0x8 * (n) + 0x204) #define MV_WIN_ETH_REMAP(n) (0x4 * (n) + 0x280) #define MV_WIN_ETH_MAX 6 #define MV_WIN_IDMA_BASE(n) (0x8 * (n) + 0xa00) #define MV_WIN_IDMA_SIZE(n) (0x8 * (n) + 0xa04) #define MV_WIN_IDMA_REMAP(n) (0x4 * (n) + 0xa60) #define MV_WIN_IDMA_CAP(n) (0x4 * (n) + 0xa70) #define MV_WIN_IDMA_MAX 8 #define MV_IDMA_CHAN_MAX 4 #define MV_WIN_XOR_BASE(n, m) (0x4 * (n) + 0xa50 + (m) * 0x100) #define MV_WIN_XOR_SIZE(n, m) (0x4 * (n) + 0xa70 + (m) * 0x100) #define MV_WIN_XOR_REMAP(n, m) (0x4 * (n) + 0xa90 + (m) * 0x100) #define MV_WIN_XOR_CTRL(n, m) (0x4 * (n) + 0xa40 + (m) * 0x100) #define MV_WIN_XOR_OVERR(n, m) (0x4 * (n) + 0xaa0 + (m) * 0x100) #define MV_WIN_XOR_MAX 8 #define MV_XOR_CHAN_MAX 2 #define MV_XOR_NON_REMAP 4 #if defined(SOC_MV_DISCOVERY) || defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DOVE) #define MV_WIN_PCIE_TARGET(n) 4 #define MV_WIN_PCIE_MEM_ATTR(n) 0xE8 #define MV_WIN_PCIE_IO_ATTR(n) 0xE0 #elif defined(SOC_MV_ARMADAXP) #define MV_WIN_PCIE_TARGET(n) (4 + (4 * ((n) % 2))) #define MV_WIN_PCIE_MEM_ATTR(n) (0xE8 + (0x10 * ((n) / 2))) #define MV_WIN_PCIE_IO_ATTR(n) (0xE0 + (0x10 * ((n) / 2))) #elif defined(SOC_MV_ARMADA38X) #define MV_WIN_PCIE_TARGET(n) ((n) == 0 ? 8 : 4) #define MV_WIN_PCIE_MEM_ATTR(n) ((n) < 2 ? 0xE8 : (0xD8 - (((n) % 2) * 0x20))) #define MV_WIN_PCIE_IO_ATTR(n) ((n) < 2 ? 0xE0 : (0xD0 - (((n) % 2) * 0x20))) #elif defined(SOC_MV_ORION) #define MV_WIN_PCIE_TARGET(n) 4 #define MV_WIN_PCIE_MEM_ATTR(n) 0x59 #define MV_WIN_PCIE_IO_ATTR(n) 0x51 #elif defined(SOC_MV_LOKIPLUS) #define MV_WIN_PCIE_TARGET(n) (3 + (n)) #define MV_WIN_PCIE_MEM_ATTR(n) 0x59 #define MV_WIN_PCIE_IO_ATTR(n) 0x51 #endif #define MV_WIN_PCI_TARGET 3 #define MV_WIN_PCI_MEM_ATTR 0x59 #define MV_WIN_PCI_IO_ATTR 0x51 #define MV_WIN_PCIE_CTRL(n) (0x10 * (((n) < 5) ? (n) : \ (n) + 1) + 0x1820) #define MV_WIN_PCIE_BASE(n) (0x10 * (((n) < 5) ? (n) : \ (n) + 1) + 0x1824) #define MV_WIN_PCIE_REMAP(n) (0x10 * (((n) < 5) ? (n) : \ (n) + 1) + 0x182C) #define MV_WIN_PCIE_MAX 6 #define MV_PCIE_BAR_CTRL(n) (0x04 * (n) + 0x1800) #define MV_PCIE_BAR_BASE(n) (0x08 * ((n) < 3 ? (n) : 4) + 0x0010) #define MV_PCIE_BAR_BASE_H(n) (0x08 * (n) + 0x0014) #define MV_PCIE_BAR_MAX 4 #define MV_PCIE_BAR_64BIT (0x4) #define MV_PCIE_BAR_PREFETCH_EN (0x8) #define MV_PCIE_CONTROL (0x1a00) #define MV_PCIE_ROOT_CMPLX (1 << 1) #define MV_WIN_SATA_CTRL(n) (0x10 * (n) + 0x30) #define MV_WIN_SATA_BASE(n) (0x10 * (n) + 0x34) #define MV_WIN_SATA_MAX 4 #if defined(SOC_MV_ARMADA38X) #define MV_BOOTROM_MEM_ADDR 0xFFF00000 #define MV_BOOTROM_WIN_SIZE 0xF #define MV_CPU_SUBSYS_REGS_LEN 0x100 +/* IO Window Control Register fields */ +#define IO_WIN_SIZE_SHIFT 16 +#define IO_WIN_SIZE_MASK 0xFFFF +#define IO_WIN_ATTR_SHIFT 8 +#define IO_WIN_ATTR_MASK 0xFF +#define IO_WIN_TGT_SHIFT 4 +#define IO_WIN_TGT_MASK 0xF +#define IO_WIN_SYNC_SHIFT 1 +#define IO_WIN_SYNC_MASK 0x1 +#define IO_WIN_ENA_SHIFT 0 +#define IO_WIN_ENA_MASK 0x1 + +#define IO_WIN_9_CTRL_OFFSET 0x98 +#define IO_WIN_9_BASE_OFFSET 0x9C + +/* Mbus decoding unit IDs and attributes */ +#define MBUS_BOOTROM_TGT_ID 0x1 +#define MBUS_BOOTROM_ATTR 0x1D + /* Internal Units Sync Barrier Control Register */ #define MV_SYNC_BARRIER_CTRL 0x84 #define MV_SYNC_BARRIER_CTRL_ALL 0xFFFF #endif #define WIN_REG_IDX_RD(pre,reg,off,base) \ static __inline uint32_t \ pre ## _ ## reg ## _read(int i) \ { \ return (bus_space_read_4(fdtbus_bs_tag, base, off(i))); \ } #define WIN_REG_IDX_RD2(pre,reg,off,base) \ static __inline uint32_t \ pre ## _ ## reg ## _read(int i, int j) \ { \ return (bus_space_read_4(fdtbus_bs_tag, base, off(i, j))); \ } \ #define WIN_REG_BASE_IDX_RD(pre,reg,off) \ static __inline uint32_t \ pre ## _ ## reg ## _read(uint32_t base, int i) \ { \ return (bus_space_read_4(fdtbus_bs_tag, base, off(i))); \ } #define WIN_REG_BASE_IDX_RD2(pre,reg,off) \ static __inline uint32_t \ pre ## _ ## reg ## _read(uint32_t base, int i, int j) \ { \ return (bus_space_read_4(fdtbus_bs_tag, base, off(i, j))); \ } #define WIN_REG_IDX_WR(pre,reg,off,base) \ static __inline void \ pre ## _ ## reg ## _write(int i, uint32_t val) \ { \ bus_space_write_4(fdtbus_bs_tag, base, off(i), val); \ } #define WIN_REG_IDX_WR2(pre,reg,off,base) \ static __inline void \ pre ## _ ## reg ## _write(int i, int j, uint32_t val) \ { \ bus_space_write_4(fdtbus_bs_tag, base, off(i, j), val); \ } #define WIN_REG_BASE_IDX_WR(pre,reg,off) \ static __inline void \ pre ## _ ## reg ## _write(uint32_t base, int i, uint32_t val) \ { \ bus_space_write_4(fdtbus_bs_tag, base, off(i), val); \ } #define WIN_REG_BASE_IDX_WR2(pre,reg,off) \ static __inline void \ pre ## _ ## reg ## _write(uint32_t base, int i, int j, uint32_t val) \ { \ bus_space_write_4(fdtbus_bs_tag, base, off(i, j), val); \ } #define WIN_REG_RD(pre,reg,off,base) \ static __inline uint32_t \ pre ## _ ## reg ## _read(void) \ { \ return (bus_space_read_4(fdtbus_bs_tag, base, off)); \ } #define WIN_REG_BASE_RD(pre,reg,off) \ static __inline uint32_t \ pre ## _ ## reg ## _read(uint32_t base) \ { \ return (bus_space_read_4(fdtbus_bs_tag, base, off)); \ } #define WIN_REG_WR(pre,reg,off,base) \ static __inline void \ pre ## _ ## reg ## _write(uint32_t val) \ { \ bus_space_write_4(fdtbus_bs_tag, base, off, val); \ } #define WIN_REG_BASE_WR(pre,reg,off) \ static __inline void \ pre ## _ ## reg ## _write(uint32_t base, uint32_t val) \ { \ bus_space_write_4(fdtbus_bs_tag, base, off, val); \ } #endif /* _MVWIN_H_ */