diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/conf/ARMADAXP armv6/sys/arm/conf/ARMADAXP --- head/sys/arm/conf/ARMADAXP 1969-12-31 16:00:00.000000000 -0800 +++ armv6/sys/arm/conf/ARMADAXP 2012-08-09 20:44:33.085971121 -0700 @@ -0,0 +1,102 @@ +# +# Custom kernel for Marvell Armada XP +# +# $FreeBSD$ +# + +ident MV-88F78XX0 +include "../mv/armadaxp/std.mv78x60" + +options SOC_MV_ARMADAXP +makeoptions MODULES_OVERRIDE="" + +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols +makeoptions WERROR="-Werror" + +#options SCHED_ULE #ULE scheduler +options SCHED_4BSD #4BSD scheduler +options INET #InterNETworking +options INET6 #IPv6 communications protocols +options FFS #Berkeley Fast Filesystem +options NFSCL #Network Filesystem Client +options NFSLOCKD #Network Lock Manager +options NFS_ROOT #NFS usable as /, requires NFSCLIENT +options BOOTP +options BOOTP_NFSROOT +options BOOTP_NFSV3 +options BOOTP_WIRED_TO=mge0 + +options GEOM_PART_GPT +options ROOTDEVNAME=\"ufs:/dev/da0p1\" + +options SYSVSHM #SYSV-style shared memory +options SYSVMSG #SYSV-style message queues +options SYSVSEM #SYSV-style semaphores +options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions +options MUTEX_NOINLINE +options RWLOCK_NOINLINE +options NO_FFS_SNAPSHOT +options NO_SWAPPING + +options SMP + +# Debugging +#options VERBOSE_SYSINIT +options ALT_BREAK_TO_DEBUGGER +options DDB +options GDB +#options DIAGNOSTIC +#options INVARIANTS #Enable calls of extra sanity checking +#options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS +options KDB +options KDB_TRACE +#options KTR +#options KTR_VERBOSE=0 +#options KTR_ENTRIES=16384 +#options KTR_MASK=(KTR_SPARE2) +#options KTR_COMPILE=KTR_ALL +#options WITNESS #Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed +#options WITNESS_KDB + +# Pseudo devices +device random +device pty +device loop +device md + +# USB +options USB_DEBUG # enable debug msgs +device usb +device ehci +device umass +device scbus +device pass +device da + +# SATA +device ata +device atadisk +#device mvs + +# Serial ports +device uart + +# I2C (TWSI) +device iic +device iicbus + +#Network +device ether +device mge # Marvell Gigabit Ethernet controller +device mii +device e1000phy +device bpf +options HZ=1000 +options DEVICE_POLLING +device vlan + +#FDT +options FDT +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=db88f78160.dts diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/armadaxp/armadaxp.c armv6/sys/arm/mv/armadaxp/armadaxp.c --- head/sys/arm/mv/armadaxp/armadaxp.c 1969-12-31 16:00:00.000000000 -0800 +++ armv6/sys/arm/mv/armadaxp/armadaxp.c 2012-08-08 12:43:44.501723716 -0700 @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 2011 Semihalf. + * 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. + * + * From: FreeBSD: src/sys/arm/mv/kirkwood/sheevaplug.c,v 1.2 2010/06/13 13:28:53 + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include + +struct resource_spec mv_gpio_res[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { SYS_RES_IRQ, 0, RF_ACTIVE }, + { -1, 0 } +}; + +uint32_t +get_tclk(void) +{ + + return (TCLK_200MHZ); +} + +uint32_t +get_l2clk(void) +{ + + return (TCLK_667MHZ); +} + +int +fdt_pci_devmap(phandle_t node, struct pmap_devmap *devmap, vm_offset_t io_va, + vm_offset_t mem_va) +{ + + return (0); +} + diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/armadaxp/armadaxp_mp.c armv6/sys/arm/mv/armadaxp/armadaxp_mp.c --- head/sys/arm/mv/armadaxp/armadaxp_mp.c 1969-12-31 16:00:00.000000000 -0800 +++ armv6/sys/arm/mv/armadaxp/armadaxp_mp.c 2012-08-08 12:43:44.501723716 -0700 @@ -0,0 +1,206 @@ +/*- + * Copyright (c) 2011 Semihalf. + * 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 +#include +#include +#include +#include +#include + +#include +#include + +#include + +static int platform_get_ncpus(void); + +#define MV_AXP_CPU_DIVCLK_BASE (MV_BASE + 0x18700) +#define CPU_DIVCLK_CTRL0 0x00 +#define CPU_DIVCLK_CTRL2_RATIO_FULL0 0x08 +#define CPU_DIVCLK_CTRL2_RATIO_FULL1 0x0c + +#define MV_COHERENCY_FABRIC_BASE (MV_MBUS_BRIDGE_BASE + 0x200) +#define COHER_FABRIC_CTRL 0x00 +#define COHER_FABRIC_CONF 0x04 + +#define CPU_PMU(x) (MV_BASE + 0x22100 + (0x100 * (x))) +#define CPU_PMU_BOOT 0x24 + +#define MP (MV_BASE + 0x20800) +#define MP_SW_RESET(x) ((x) * 8) + +#define CPU_RESUME_CONTROL (0x20988) + +/* Coherency Fabric registers */ +static uint32_t +read_coher_fabric(uint32_t reg) +{ + + return (bus_space_read_4(fdtbus_bs_tag, MV_COHERENCY_FABRIC_BASE, reg)); +} + +static void +write_coher_fabric(uint32_t reg, uint32_t val) +{ + + bus_space_write_4(fdtbus_bs_tag, MV_COHERENCY_FABRIC_BASE, reg, val); +} + +/* Coherency Fabric registers */ +static uint32_t +read_cpu_clkdiv(uint32_t reg) +{ + + return (bus_space_read_4(fdtbus_bs_tag, MV_AXP_CPU_DIVCLK_BASE, reg)); +} + +static void +write_cpu_clkdiv(uint32_t reg, uint32_t val) +{ + + bus_space_write_4(fdtbus_bs_tag, MV_AXP_CPU_DIVCLK_BASE, reg, val); +} + +void +platform_mp_setmaxid(void) +{ + + mp_maxid = 3; +} + +int +platform_mp_probe(void) +{ + + mp_ncpus = platform_get_ncpus(); + + return (mp_ncpus > 1); +} + +void +platform_mp_init_secondary(void) +{ +} + +void mpentry(void); +void mptramp(void); + +static void +initialize_coherency_fabric(void) +{ + uint32_t val, cpus, mask; + + cpus = platform_get_ncpus(); + mask = (1 << cpus) - 1; + val = read_coher_fabric(COHER_FABRIC_CTRL); + val |= (mask << 24); + write_coher_fabric(COHER_FABRIC_CTRL, val); + + val = read_coher_fabric(COHER_FABRIC_CONF); + val |= (mask << 24); + write_coher_fabric(COHER_FABRIC_CONF, val); +} + + +void +platform_mp_start_ap(void) +{ + uint32_t reg, *ptr, cpu_num; + + /* Copy boot code to SRAM */ + *((unsigned int*)(0xf1020240)) = 0xffff0101; + *((unsigned int*)(0xf1008500)) = 0xffff0003; + + pmap_kenter_nocache(0x880f0000, 0xffff0000); + reg = 0x880f0000; + + for (ptr = (uint32_t *)mptramp; ptr < (uint32_t *)mpentry; + ptr++, reg += 4) + *((uint32_t *)reg) = *ptr; + + if (mp_ncpus > 1) { + reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL0); + reg &= 0x00ffffff; + reg |= 0x01000000; + write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL0, reg); + } + if (mp_ncpus > 2) { + reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1); + reg &= 0xff00ffff; + reg |= 0x00010000; + write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1, reg); + } + if (mp_ncpus > 3) { + reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1); + reg &= 0x00ffffff; + reg |= 0x01000000; + write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1, reg); + } + + reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL0); + reg |= ((0x1 << (mp_ncpus - 1)) - 1) << 21; + write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg); + reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL0); + reg |= 0x01000000; + write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg); + + DELAY(100); + reg &= ~(0xf << 21); + write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg); + DELAY(100); + + bus_space_write_4(fdtbus_bs_tag, MV_BASE, CPU_RESUME_CONTROL, 0); + + for (cpu_num = 1; cpu_num < mp_ncpus; cpu_num++ ) + bus_space_write_4(fdtbus_bs_tag, CPU_PMU(cpu_num), CPU_PMU_BOOT, + pmap_kextract(mpentry)); + + cpu_idcache_wbinv_all(); + + for (cpu_num = 1; cpu_num < mp_ncpus; cpu_num++ ) + bus_space_write_4(fdtbus_bs_tag, MP, MP_SW_RESET(cpu_num), 0); + + /* XXX: Temporary workaround for hangup after releasing AP's */ + wmb(); + DELAY(10); + + initialize_coherency_fabric(); +} + +static int +platform_get_ncpus(void) +{ + + return ((read_coher_fabric(COHER_FABRIC_CONF) & 0xf) + 1); +} + +void +platform_ipi_send(cpuset_t cpus, u_int ipi) +{ + + pic_ipi_send(cpus, ipi); +} diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/armadaxp/files.armadaxp armv6/sys/arm/mv/armadaxp/files.armadaxp --- head/sys/arm/mv/armadaxp/files.armadaxp 1969-12-31 16:00:00.000000000 -0800 +++ armv6/sys/arm/mv/armadaxp/files.armadaxp 2012-08-08 12:43:44.502723838 -0700 @@ -0,0 +1,6 @@ +# $FreeBSD: src/sys/arm/mv/kirkwood/files.db88f6xxx,v 1.1 2008/10/13 20:07:13 raj Exp $ + +arm/mv/armadaxp/armadaxp.c standard +arm/mv/mpic.c standard +arm/mv/rtc.c standard +arm/mv/armadaxp/armadaxp_mp.c optional smp diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/armadaxp/std.armadaxp armv6/sys/arm/mv/armadaxp/std.armadaxp --- head/sys/arm/mv/armadaxp/std.armadaxp 1969-12-31 16:00:00.000000000 -0800 +++ armv6/sys/arm/mv/armadaxp/std.armadaxp 2012-08-08 12:43:44.500723818 -0700 @@ -0,0 +1,15 @@ +# $FreeBSD: src/sys/arm/mv/kirkwood/std.db88f6xxx,v 1.1 2008/10/13 20:07:13 raj Exp $ + +# kernel gets loaded at 0x00f00000 by the loader, but runs at virtual address +# 0xc0f00000. RAM starts at 0. We put the pagetable at a reasonable place +# in memory, but may need to bounce it higher if there's a problem with this. +# We could paper over this by loading the kernel at 0xc0000000 virtual, but +# that leads to other complications, so we'll just reclaim the lower region of +# ram after we're loaded. Put the page tables for startup at 1MB. +makeoptions KERNPHYSADDR=0x00f00000 +makeoptions KERNVIRTADDR=0xc0f00000 + +options KERNPHYSADDR=0x00f00000 +options KERNVIRTADDR=0xc0f00000 +options PHYSADDR=0x00000000 +options STARTUP_PAGETABLE_ADDR=0x00100000 diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/armadaxp/std.mv78x60 armv6/sys/arm/mv/armadaxp/std.mv78x60 --- head/sys/arm/mv/armadaxp/std.mv78x60 1969-12-31 16:00:00.000000000 -0800 +++ armv6/sys/arm/mv/armadaxp/std.mv78x60 2012-08-08 12:43:44.500723818 -0700 @@ -0,0 +1,5 @@ +# $FreeBSD: src/sys/arm/mv/kirkwood/std.db88f6xxx,v 1.1 2008/10/13 20:07:13 raj Exp $ + +include "../mv/std-pj4b.mv" +include "../mv/armadaxp/std.armadaxp" +files "../mv/armadaxp/files.armadaxp" diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/common.c armv6/sys/arm/mv/common.c --- head/sys/arm/mv/common.c 2012-08-08 18:48:36.540767997 -0700 +++ armv6/sys/arm/mv/common.c 2012-08-09 12:08:28.495724513 -0700 @@ -1,5 +1,5 @@ /*- - * Copyright (C) 2008 MARVELL INTERNATIONAL LTD. + * Copyright (C) 2008-2011 MARVELL INTERNATIONAL LTD. * All rights reserved. * * Developed by Semihalf. @@ -29,8 +29,10 @@ * SUCH DAMAGE. */ +#include "opt_global.h" + #include -__FBSDID("$FreeBSD: head/sys/arm/mv/common.c 238873 2012-07-28 21:56:24Z hrs $"); +__FBSDID("$FreeBSD: projects/armv6/sys/arm/mv/common.c 239154 2012-08-09 19:08:08Z gonzo $"); #include #include @@ -36,17 +38,27 @@ #include #include #include +#include +#include +#include #include #include #include #include +#include #include #include #include + +MALLOC_DEFINE(M_IDMA, "idma", "idma dma test memory"); + +#define IDMA_DEBUG +#undef IDMA_DEBUG + #define MAX_CPU_WIN 5 #ifdef DEBUG @@ -64,7 +76,9 @@ static int win_eth_can_remap(int i); +#ifndef SOC_MV_FREY static int decode_win_cpu_valid(void); +#endif static int decode_win_usb_valid(void); static int decode_win_eth_valid(void); static int decode_win_pcie_valid(void); @@ -73,10 +87,11 @@ static int decode_win_idma_valid(void); static int decode_win_xor_valid(void); +#ifndef SOC_MV_FREY static void decode_win_cpu_setup(void); +#endif static void decode_win_usb_setup(u_long); static void decode_win_eth_setup(u_long); -static void decode_win_pcie_setup(u_long); static void decode_win_sata_setup(u_long); static void decode_win_cesa_setup(u_long); static void decode_win_idma_setup(u_long); @@ -93,7 +108,6 @@ static int win_cpu_from_dt(void); static int fdt_win_setup(void); -static uint32_t used_cpu_wins; static uint32_t dev_mask = 0; static int cpu_wins_no = 0; static int eth_port = 0; @@ -101,7 +115,7 @@ static struct decode_win cpu_win_tbl[MAX_CPU_WIN]; -static const struct decode_win *cpu_wins = cpu_win_tbl; +const struct decode_win *cpu_wins = cpu_win_tbl; typedef void (*decode_win_setup_t)(u_long); typedef void (*dump_win_t)(u_long); @@ -251,15 +265,23 @@ uint32_t ef = 0; soc_id(&dev, &rev); - if (dev == MV_DEV_88F6281 || - dev == MV_DEV_88F6282 || - dev == MV_DEV_MV78100_Z0 || - dev == MV_DEV_MV78100) + + switch (dev) { + case MV_DEV_88F6281: + case MV_DEV_88F6282: + case MV_DEV_88RC8180: + case MV_DEV_MV78100_Z0: + case MV_DEV_MV78100: __asm __volatile("mrc p15, 1, %0, c15, c1, 0" : "=r" (ef)); - else if (dev == MV_DEV_88F5182 || dev == MV_DEV_88F5281) + break; + case MV_DEV_88F5182: + case MV_DEV_88F5281: __asm __volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (ef)); - else if (bootverbose) - printf("This ARM Core does not support any extra features\n"); + break; + default: + if (bootverbose) + printf("This ARM Core does not support any extra features\n"); + } return (ef); } @@ -272,7 +294,7 @@ soc_power_ctrl_get(uint32_t mask) { -#ifndef SOC_MV_ORION +#if !defined(SOC_MV_ORION) && !defined(SOC_MV_LOKIPLUS) && !defined(SOC_MV_FREY) if (mask != CPU_PM_CTRL_NONE) mask &= read_cpu_ctrl(CPU_PM_CTRL); @@ -290,7 +312,7 @@ soc_power_ctrl_set(uint32_t mask) { -#ifndef SOC_MV_ORION +#if !defined(SOC_MV_ORION) && !defined(SOC_MV_LOKIPLUS) if (mask != CPU_PM_CTRL_NONE) write_cpu_ctrl(CPU_PM_CTRL, mask); #endif @@ -313,7 +335,7 @@ static void soc_identify(void) { - uint32_t d, r; + uint32_t d, r, size, mode; const char *dev; const char *rev; @@ -353,6 +375,20 @@ else if (r == 3) rev = "A1"; break; + case MV_DEV_88RC8180: + dev = "Marvell 88RC8180"; + break; + case MV_DEV_88RC9480: + dev = "Marvell 88RC9480"; + break; + case MV_DEV_88RC9580: + dev = "Marvell 88RC9580"; + break; + case MV_DEV_88F6781: + dev = "Marvell 88F6781"; + if (r == 2) + rev = "Y0"; + break; case MV_DEV_88F6282: dev = "Marvell 88F6282"; if (r == 0) @@ -366,6 +402,15 @@ case MV_DEV_MV78100: dev = "Marvell MV78100"; break; + case MV_DEV_MV78160: + dev = "Marvell MV78160"; + break; + case MV_DEV_MV78260: + dev = "Marvell MV78260"; + break; + case MV_DEV_MV78460: + dev = "Marvell MV78460"; + break; default: dev = "UNKNOWN"; break; @@ -376,7 +421,28 @@ printf(" rev %s", rev); printf(", TClock %dMHz\n", get_tclk() / 1000 / 1000); - /* TODO add info on currently set endianess */ + mode = read_cpu_ctrl(CPU_CONFIG); + printf(" Instruction cache prefetch %s, data cache prefetch %s\n", + (mode & CPU_CONFIG_IC_PREF) ? "enabled" : "disabled", + (mode & CPU_CONFIG_DC_PREF) ? "enabled" : "disabled"); + + switch (d) { + case MV_DEV_88F6281: + mode = read_cpu_ctrl(CPU_L2_CONFIG) & CPU_L2_CONFIG_MODE; + printf(" 256KB 4-way set-associative %s unified L2 cache\n", + mode ? "write-through" : "write-back"); + break; + case MV_DEV_MV78100: + mode = read_cpu_ctrl(CPU_CONTROL); + size = mode & CPU_CONTROL_L2_SIZE; + mode = mode & CPU_CONTROL_L2_MODE; + printf(" %s set-associative %s unified L2 cache\n", + size ? "256KB 4-way" : "512KB 8-way", + mode ? "write-through" : "write-back"); + break; + default: + break; + } } static void @@ -393,6 +459,17 @@ SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, NULL); +#ifdef KDB +static void +mv_enter_debugger(void *dummy) +{ + + if (boothowto & RB_KDB) + kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); +} +SYSINIT(mv_enter_debugger, SI_SUB_CPU, SI_ORDER_ANY, mv_enter_debugger, NULL); +#endif + int soc_decode_win(void) { @@ -412,6 +489,7 @@ /* Retrieve our ID: some windows facilities vary between SoC models */ soc_id(&dev, &rev); +#ifndef SOC_MV_FREY if (!decode_win_cpu_valid() || !decode_win_usb_valid() || !decode_win_eth_valid() || !decode_win_idma_valid() || !decode_win_pcie_valid() || !decode_win_sata_valid() || @@ -419,6 +497,13 @@ return (EINVAL); decode_win_cpu_setup(); +#else + if (!decode_win_usb_valid() || + !decode_win_eth_valid() || !decode_win_idma_valid() || + !decode_win_pcie_valid() || !decode_win_sata_valid() || + !decode_win_cesa_valid() || !decode_win_xor_valid()) + return (EINVAL); +#endif if (MV_DUMP_WIN) soc_dump_decode_win(); @@ -433,6 +518,7 @@ /************************************************************************** * Decode windows registers accessors **************************************************************************/ +#if !defined(SOC_MV_FREY) WIN_REG_IDX_RD(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE) WIN_REG_IDX_RD(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE) WIN_REG_IDX_RD(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE) @@ -441,9 +527,7 @@ WIN_REG_IDX_WR(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE) WIN_REG_IDX_WR(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE) WIN_REG_IDX_WR(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE) - -WIN_REG_IDX_RD(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE) -WIN_REG_IDX_RD(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE) +#endif WIN_REG_BASE_IDX_RD(win_usb, cr, MV_WIN_USB_CTRL) WIN_REG_BASE_IDX_RD(win_usb, br, MV_WIN_USB_BASE) @@ -482,7 +566,10 @@ WIN_REG_BASE_IDX_WR(win_pcie, cr, MV_WIN_PCIE_CTRL); WIN_REG_BASE_IDX_WR(win_pcie, br, MV_WIN_PCIE_BASE); WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP); -WIN_REG_BASE_IDX_WR(pcie, bar, MV_PCIE_BAR); +WIN_REG_BASE_IDX_RD(pcie_bar, br, MV_PCIE_BAR_BASE); +WIN_REG_BASE_IDX_WR(pcie_bar, br, MV_PCIE_BAR_BASE); +WIN_REG_BASE_IDX_WR(pcie_bar, brh, MV_PCIE_BAR_BASE_H); +WIN_REG_BASE_IDX_WR(pcie_bar, cr, MV_PCIE_BAR_CTRL); WIN_REG_BASE_IDX_RD(win_idma, br, MV_WIN_IDMA_BASE) WIN_REG_BASE_IDX_RD(win_idma, sz, MV_WIN_IDMA_SIZE) @@ -499,7 +586,44 @@ WIN_REG_BASE_IDX_RD(win_sata, br, MV_WIN_SATA_BASE); WIN_REG_BASE_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL); WIN_REG_BASE_IDX_WR(win_sata, br, MV_WIN_SATA_BASE); +#ifndef SOC_MV_DOVE +WIN_REG_IDX_RD(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE) +WIN_REG_IDX_RD(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE) +#else +/* + * On 88F6781 (Dove) SoC DDR Controller is accessed through + * single MBUS <-> AXI bridge. In this case we provide emulated + * ddr_br_read() and ddr_sz_read() functions to keep compatibility + * with common decoding windows setup code. + */ +static inline uint32_t ddr_br_read(int i) +{ + uint32_t mmap; + + /* Read Memory Address Map Register for CS i */ + mmap = bus_space_read_4(fdtbus_bs_tag, MV_DDR_CADR_BASE + (i * 0x10), 0); + + /* Return CS i base address */ + return (mmap & 0xFF000000); +} + +static inline uint32_t ddr_sz_read(int i) +{ + uint32_t mmap, size; + + /* Read Memory Address Map Register for CS i */ + mmap = bus_space_read_4(fdtbus_bs_tag, MV_DDR_CADR_BASE + (i * 0x10), 0); + + /* Extract size of CS space in 64kB units */ + size = (1 << ((mmap >> 16) & 0x0F)); + + /* Return CS size and enable/disable status */ + return (((size - 1) << 16) | (mmap & 0x01)); +} +#endif + +#if !defined(SOC_MV_FREY) /************************************************************************** * Decode windows helper routines **************************************************************************/ @@ -545,9 +669,12 @@ if ((dev == MV_DEV_88F5182 && i < 2) || (dev == MV_DEV_88F5281 && i < 4) || (dev == MV_DEV_88F6281 && i < 4) || + (dev == MV_DEV_88RC8180 && i < 2) || + (dev == MV_DEV_88F6781 && i < 4) || (dev == MV_DEV_88F6282 && i < 4) || (dev == MV_DEV_MV78100 && i < 8) || - (dev == MV_DEV_MV78100_Z0 && i < 8)) + (dev == MV_DEV_MV78100_Z0 && i < 8) || + ((dev & MV_DEV_FAMILY_MASK) == MV_DEV_DISCOVERY && i < 8)) return (1); return (0); @@ -600,7 +727,7 @@ rv = 0; } - if (cpu_wins[i].remap >= 0 && win_cpu_can_remap(i) != 1) { + if (cpu_wins[i].remap != ~0 && win_cpu_can_remap(i) != 1) { printf("CPU window#%d: not capable of remapping, but " "val 0x%08x defined\n", i, cpu_wins[i].remap); rv = 0; @@ -620,6 +747,13 @@ continue; } + if (b != (b & ~(s - 1))) { + printf("CPU window#%d: address 0x%08x is not aligned " + "to 0x%08x\n", i, b, s); + rv = 0; + continue; + } + j = decode_win_overlap(i, cpu_wins_no, &cpu_wins[0]); if (j >= 0) { printf("CPU window#%d: (0x%08x - 0x%08x) overlaps " @@ -635,21 +769,39 @@ int decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size, - int remap) + vm_paddr_t remap) { uint32_t br, cr; - int win; + int win, i; - if (used_cpu_wins >= MV_WIN_CPU_MAX) - return (0); + if (remap == ~0) { + win = MV_WIN_CPU_MAX - 1; + i = -1; + } else { + win = 0; + i = 1; + } - win = used_cpu_wins++; + while ((win >= 0) && (win < MV_WIN_CPU_MAX)) { + cr = win_cpu_cr_read(win); + if ((cr & MV_WIN_CPU_ENABLE_BIT) == 0) + break; + if ((cr & ((0xff << MV_WIN_CPU_ATTR_SHIFT) | + (0x1f << MV_WIN_CPU_TARGET_SHIFT))) == + ((attr << MV_WIN_CPU_ATTR_SHIFT) | + (target << MV_WIN_CPU_TARGET_SHIFT))) + break; + win += i; + } + if ((win < 0) || (win >= MV_WIN_CPU_MAX) || + ((remap != ~0) && (win_cpu_can_remap(win) == 0))) + return (-1); br = base & 0xffff0000; win_cpu_br_write(win, br); if (win_cpu_can_remap(win)) { - if (remap >= 0) { + if (remap != ~0) { win_cpu_remap_l_write(win, remap & 0xffff0000); win_cpu_remap_h_write(win, 0); } else { @@ -663,7 +815,8 @@ } } - cr = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1; + cr = ((size - 1) & 0xffff0000) | (attr << MV_WIN_CPU_ATTR_SHIFT) | + (target << MV_WIN_CPU_TARGET_SHIFT) | MV_WIN_CPU_ENABLE_BIT; win_cpu_cr_write(win, cr); return (0); @@ -674,8 +827,6 @@ { int i; - used_cpu_wins = 0; - /* Disable all CPU windows */ for (i = 0; i < MV_WIN_CPU_MAX; i++) { win_cpu_cr_write(i, 0); @@ -693,7 +844,7 @@ cpu_wins[i].size, cpu_wins[i].remap); } - +#endif /* * Check if we're able to cover all active DDR banks. */ @@ -746,6 +897,13 @@ uint32_t ddr_attr(int i) { + uint32_t dev, rev; + + soc_id(&dev, &rev); + if (dev == MV_DEV_88RC8180) + return ((ddr_sz_read(i) & 0xf0) >> 4); + if (dev == MV_DEV_88F6781) + return (0); return (i == 0 ? 0xe : (i == 1 ? 0xd : @@ -756,8 +914,21 @@ uint32_t ddr_target(int i) { + uint32_t dev, rev; + + soc_id(&dev, &rev); + if (dev == MV_DEV_88RC8180) { + i = (ddr_sz_read(i) & 0xf0) >> 4; + return (i == 0xe ? 0xc : + (i == 0xd ? 0xd : + (i == 0xb ? 0xe : + (i == 0x7 ? 0xf : 0xc)))); + } - /* Mbus unit ID is 0x0 for DDR SDRAM controller */ + /* + * On SOCs other than 88RC8180 Mbus unit ID for + * DDR SDRAM controller is always 0x0. + */ return (0); } @@ -840,7 +1011,7 @@ /* ETH encode windows 0-3 have remap capability */ if (i < 4) return (1); - + return (0); } @@ -901,6 +1072,12 @@ win_eth_epap_read(base)); } +#if defined(SOC_MV_LOKIPLUS) +#define MV_WIN_ETH_DDR_TRGT(n) 0 +#else +#define MV_WIN_ETH_DDR_TRGT(n) ddr_target(n) +#endif + static void decode_win_eth_setup(u_long base) { @@ -927,7 +1104,7 @@ for (i = 0; i < MV_WIN_DDR_MAX; i++) if (ddr_is_active(i)) { - br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i); + br = ddr_base(i) | (ddr_attr(i) << 8) | MV_WIN_ETH_DDR_TRGT(i); sz = ((ddr_size(i) - 1) & 0xffff0000); /* Set the first free ETH window */ @@ -961,15 +1138,21 @@ * PCIE windows routines **************************************************************************/ -static void +void decode_win_pcie_setup(u_long base) { - uint32_t size = 0; + uint32_t size = 0, ddrbase = ~0; uint32_t cr, br; int i, j; - for (i = 0; i < MV_PCIE_BAR_MAX; i++) - pcie_bar_write(base, i, 0); + for (i = 0; i < MV_PCIE_BAR_MAX; i++) { + pcie_bar_br_write(base, i, + MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN); + if (i < 3) + pcie_bar_brh_write(base, i, 0); + if (i > 0) + pcie_bar_cr_write(base, i, 0); + } for (i = 0; i < MV_WIN_PCIE_MAX; i++) { win_pcie_cr_write(base, i, 0); @@ -977,6 +1160,13 @@ win_pcie_remap_write(base, i, 0); } + /* On End-Point only set BAR size to 1MB regardless of DDR size */ + if ((bus_space_read_4(fdtbus_bs_tag, base, MV_PCIE_CONTROL) + & MV_PCIE_ROOT_CMPLX) == 0) { + pcie_bar_cr_write(base, 1, 0xf0000 | 1); + return; + } + for (i = 0; i < MV_WIN_DDR_MAX; i++) { if (ddr_is_active(i)) { /* Map DDR to BAR 1 */ @@ -984,6 +1174,8 @@ size += ddr_size(i) & 0xffff0000; cr |= (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1; br = ddr_base(i); + if (br < ddrbase) + ddrbase = br; /* Use the first available PCIE window */ for (j = 0; j < MV_WIN_PCIE_MAX; j++) { @@ -1003,7 +1195,11 @@ * form value passed to register to get correct value. */ size -= 0x10000; - pcie_bar_write(base, 0, size | 1); + pcie_bar_cr_write(base, 1, size | 1); + pcie_bar_br_write(base, 1, ddrbase | + MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN); + pcie_bar_br_write(base, 0, fdt_immr_pa | + MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN); } static int @@ -1289,7 +1485,6 @@ /* * Set channel protection 'val' for window 'w' on channel 'c' */ - static void xor_chan_write(u_long base, int c, int e, int w, int val) { @@ -1748,7 +1943,7 @@ /* Retrieve 'ranges' property of '/localbus' node. */ if ((err = fdt_get_ranges("/localbus", ranges, sizeof(ranges), &tuples, &tuple_size)) != 0) - return (err); + return (0); /* * Fill CPU decode windows table. @@ -1763,9 +1958,9 @@ cpu_win_tbl[t].attr = fdt32_to_cpu(ranges[i + 1]); cpu_win_tbl[t].base = fdt32_to_cpu(ranges[i + 2]); cpu_win_tbl[t].size = fdt32_to_cpu(ranges[i + 3]); - cpu_win_tbl[t].remap = -1; + cpu_win_tbl[t].remap = ~0; debugf("target = 0x%0x attr = 0x%0x base = 0x%0x " - "size = 0x%0x remap = %d\n", cpu_win_tbl[t].target, + "size = 0x%0x remap = 0x%0x\n", cpu_win_tbl[t].target, cpu_win_tbl[t].attr, cpu_win_tbl[t].base, cpu_win_tbl[t].size, cpu_win_tbl[t].remap); } @@ -1792,7 +1987,7 @@ cpu_win_tbl[t].attr = MV_WIN_CESA_ATTR; cpu_win_tbl[t].base = sram_base; cpu_win_tbl[t].size = sram_size; - cpu_win_tbl[t].remap = -1; + cpu_win_tbl[t].remap = ~0; debugf("sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size); return (0); @@ -1810,15 +2005,12 @@ if (node == -1) panic("fdt_win_setup: no root node"); - node = fdt_find_compatible(node, "simple-bus", 1); - if (node == 0) - return (ENXIO); - /* - * Traverse through all children of simple-bus node, and retrieve - * decode windows data for devices (if applicable). + * Traverse through all children of root and simple-bus nodes. + * For each found device retrieve decode windows data (if applicable). */ - for (child = OF_child(node); child != 0; child = OF_peer(child)) + child = OF_child(node); + while (child != 0) { for (i = 0; soc_nodes[i].compat != NULL; i++) { soc_node = &soc_nodes[i]; @@ -1830,7 +2022,7 @@ if (err != 0) return (err); - base += fdt_immr_va; + base = (base & 0x000fffff) | fdt_immr_va; if (soc_node->decode_handler != NULL) soc_node->decode_handler(base); else @@ -1840,6 +2032,19 @@ soc_node->dump_handler(base); } + /* + * Once done with root-level children let's move down to + * simple-bus and its children. + */ + child = OF_peer(child); + if ((child == 0) && (node == OF_finddevice("/"))) { + node = fdt_find_compatible(node, "simple-bus", 1); + if (node == 0) + return (ENXIO); + child = OF_child(node); + } + } + return (0); } @@ -1870,7 +2075,8 @@ int *pol) { - if (!fdt_is_compatible(node, "mrvl,pic")) + if (!fdt_is_compatible(node, "mrvl,pic") && + !fdt_is_compatible(node, "mrvl,mpic")) return (ENXIO); *interrupt = fdt32_to_cpu(intr[0]); diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/discovery/files.db78xxx armv6/sys/arm/mv/discovery/files.db78xxx --- head/sys/arm/mv/discovery/files.db78xxx 2012-08-08 12:42:08.294723967 -0700 +++ armv6/sys/arm/mv/discovery/files.db78xxx 2012-08-12 18:14:01.024724616 -0700 @@ -1,3 +1,5 @@ -# $FreeBSD: head/sys/arm/mv/discovery/files.db78xxx 209131 2010-06-13 13:28:53Z raj $ +# $FreeBSD: projects/armv6/sys/arm/mv/discovery/files.db78xxx 239223 2012-08-13 01:14:00Z gonzo $ arm/mv/discovery/discovery.c standard +arm/mv/ic.c standard + diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/files.mv armv6/sys/arm/mv/files.mv --- head/sys/arm/mv/files.mv 2012-08-08 13:43:35.633723982 -0700 +++ armv6/sys/arm/mv/files.mv 2012-08-09 12:08:28.497724684 -0700 @@ -14,14 +14,17 @@ # arm/arm/bus_space_generic.c standard arm/arm/cpufunc_asm_arm10.S standard +arm/arm/cpufunc_asm_arm11.S standard +arm/arm/cpufunc_asm_armv5.S standard arm/arm/cpufunc_asm_armv5_ec.S standard +arm/arm/cpufunc_asm_armv7.S standard arm/arm/cpufunc_asm_sheeva.S standard +arm/arm/cpufunc_asm_pj4b.S standard arm/arm/irq_dispatch.S standard arm/mv/bus_space.c standard arm/mv/common.c standard arm/mv/gpio.c standard -arm/mv/ic.c standard arm/mv/mv_localbus.c standard arm/mv/mv_machdep.c standard arm/mv/mv_pci.c optional pci diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/kirkwood/files.kirkwood armv6/sys/arm/mv/kirkwood/files.kirkwood --- head/sys/arm/mv/kirkwood/files.kirkwood 2012-08-08 12:42:08.276724004 -0700 +++ armv6/sys/arm/mv/kirkwood/files.kirkwood 2012-08-12 18:14:01.025725640 -0700 @@ -1,4 +1,5 @@ -# $FreeBSD: head/sys/arm/mv/kirkwood/files.kirkwood 196533 2009-08-25 09:39:11Z raj $ +# $FreeBSD: projects/armv6/sys/arm/mv/kirkwood/files.kirkwood 239223 2012-08-13 01:14:00Z gonzo $ +arm/mv/ic.c standard arm/mv/rtc.c standard arm/mv/kirkwood/kirkwood.c standard diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/mpic.c armv6/sys/arm/mv/mpic.c --- head/sys/arm/mv/mpic.c 1969-12-31 16:00:00.000000000 -0800 +++ armv6/sys/arm/mv/mpic.c 2012-08-08 12:43:45.606723752 -0700 @@ -0,0 +1,304 @@ +/*- + * Copyright (c) 2006 Benno Rice. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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/xscale/pxa2x0/pxa2x0_icu.c, rev 1 + * from: FreeBSD: src/sys/arm/mv/ic.c,v 1.5 2011/02/08 01:49:30 + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#define IRQ_ERR 4 +#define MAIN_IRQS 116 + +#define IRQ_MASK 0x3ff + +#define MPIC_CTRL 0x0 +#define MPIC_SOFT_INT 0x4 +#define MPIC_ERR_CAUSE 0x20 +#define MPIC_ISE 0x30 +#define MPIC_ICE 0x34 + + +#define MPIC_IN_DOORBELL 0x78 +#define MPIC_IN_DOORBELL_MASK 0x7c +#define MPIC_CTP 0xb0 +#define MPIC_CTP 0xb0 +#define MPIC_IIACK 0xb4 +#define MPIC_ISM 0xb8 +#define MPIC_ICM 0xbc +#define MPIC_ERR_MASK 0xec0 + +struct mv_mpic_softc { + struct resource * mpic_res[2]; + bus_space_tag_t mpic_bst; + bus_space_handle_t mpic_bsh; + bus_space_tag_t cpu_bst; + bus_space_handle_t cpu_bsh; + int mpic_high_regs; + int mpic_error_regs; +}; + +static struct resource_spec mv_mpic_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { SYS_RES_MEMORY, 1, RF_ACTIVE }, + { -1, 0 } +}; + +static struct mv_mpic_softc *mv_mpic_sc = NULL; + +void mpic_send_ipi(int cpus, u_int ipi); + +static int mv_mpic_probe(device_t); +static int mv_mpic_attach(device_t); +uint32_t mv_mpic_get_cause(void); +uint32_t mv_mpic_get_cause_err(void); +static void arm_mask_irq_err(uintptr_t); +static void arm_unmask_irq_err(uintptr_t); + +#define MPIC_CPU_WRITE(softc, reg, val) \ + bus_space_write_4((softc)->cpu_bst, (softc)->cpu_bsh, (reg), (val)) +#define MPIC_CPU_READ(softc, reg) \ + bus_space_read_4((softc)->cpu_bst, (softc)->cpu_bsh, (reg)) + +static int +mv_mpic_probe(device_t dev) +{ + + if (!ofw_bus_is_compatible(dev, "mrvl,mpic")) + return (ENXIO); + + device_set_desc(dev, "Marvell Integrated Interrupt Controller"); + return (0); +} + +static int +mv_mpic_attach(device_t dev) +{ + struct mv_mpic_softc *sc; + int error; + + sc = (struct mv_mpic_softc *)device_get_softc(dev); + + if (mv_mpic_sc != NULL) + return (ENXIO); + mv_mpic_sc = sc; + + error = bus_alloc_resources(dev, mv_mpic_spec, sc->mpic_res); + if (error) { + device_printf(dev, "could not allocate resources\n"); + return (ENXIO); + } + + sc->mpic_bst = rman_get_bustag(sc->mpic_res[0]); + sc->mpic_bsh = rman_get_bushandle(sc->mpic_res[0]); + + sc->cpu_bst = rman_get_bustag(sc->mpic_res[1]); + sc->cpu_bsh = rman_get_bushandle(sc->mpic_res[1]); + + bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh, + MPIC_CTRL, 1); + MPIC_CPU_WRITE(mv_mpic_sc, MPIC_CTP, 0); + + return (0); +} + +static device_method_t mv_mpic_methods[] = { + DEVMETHOD(device_probe, mv_mpic_probe), + DEVMETHOD(device_attach, mv_mpic_attach), + { 0, 0 } +}; + +static driver_t mv_mpic_driver = { + "mpic", + mv_mpic_methods, + sizeof(struct mv_mpic_softc), +}; + +static devclass_t mv_mpic_devclass; + +DRIVER_MODULE(mpic, simplebus, mv_mpic_driver, mv_mpic_devclass, 0, 0); + +int +arm_get_next_irq(int last) +{ + u_int irq, next = -1; + + irq = mv_mpic_get_cause() & IRQ_MASK; + CTR2(KTR_INTR, "%s: irq:%#x", __func__, irq); + + if (irq != IRQ_MASK) { + if (irq == IRQ_ERR) + irq = mv_mpic_get_cause_err(); + next = irq; + } + + CTR3(KTR_INTR, "%s: last=%d, next=%d", __func__, last, next); + return (next); +} + +/* + * XXX We can make arm_enable_irq to operate on ICE and then mask/unmask only + * by ISM/ICM and remove access to ICE in masking operation + */ +void +arm_mask_irq(uintptr_t nb) +{ + + MPIC_CPU_WRITE(mv_mpic_sc, MPIC_CTP, 1); + + if (nb < MAIN_IRQS) { + bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh, + MPIC_ICE, nb); + MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ISM, nb); + } else + arm_mask_irq_err(nb); +} + + +static void +arm_mask_irq_err(uintptr_t nb) +{ + uint32_t mask; + uint8_t bit_off; + + bit_off = nb - MAIN_IRQS; + mask = MPIC_CPU_READ(mv_mpic_sc, MPIC_ERR_MASK); + mask &= ~(1 << bit_off); + MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ERR_MASK, mask); +} + +void +arm_unmask_irq(uintptr_t nb) +{ + + MPIC_CPU_WRITE(mv_mpic_sc, MPIC_CTP, 0); + + if (nb < MAIN_IRQS) { + bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh, + MPIC_ISE, nb); + MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ICM, nb); + } else + arm_unmask_irq_err(nb); + + if (nb == 0) + MPIC_CPU_WRITE(mv_mpic_sc, MPIC_IN_DOORBELL_MASK, 0xffffffff); +} + +void +arm_unmask_irq_err(uintptr_t nb) +{ + uint32_t mask; + uint8_t bit_off; + + bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh, + MPIC_ISE, IRQ_ERR); + MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ICM, IRQ_ERR); + + bit_off = nb - MAIN_IRQS; + mask = MPIC_CPU_READ(mv_mpic_sc, MPIC_ERR_MASK); + mask |= (1 << bit_off); + MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ERR_MASK, mask); +} + +uint32_t +mv_mpic_get_cause(void) +{ + + return (MPIC_CPU_READ(mv_mpic_sc, MPIC_IIACK)); +} + +uint32_t +mv_mpic_get_cause_err(void) +{ + uint32_t err_cause; + uint8_t bit_off; + + err_cause = bus_space_read_4(mv_mpic_sc->mpic_bst, + mv_mpic_sc->mpic_bsh, MPIC_ERR_CAUSE); + + if (err_cause) + bit_off = ffs(err_cause) - 1; + else + return (-1); + return (MAIN_IRQS + bit_off); +} + +#if defined(SMP) +void +pic_ipi_send(cpuset_t cpus, u_int ipi) +{ + uint32_t val, i; + + val = 0x00000000; + for (i = 0; i < MAXCPU; i++) + if (CPU_ISSET(i, &cpus)) + val |= (1 << (8 + i)); + val |= ipi; + bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh, + MPIC_SOFT_INT, val); +} + +int +pic_ipi_get(int i __unused) +{ + uint32_t val; + + val = MPIC_CPU_READ(mv_mpic_sc, MPIC_IN_DOORBELL); + if (val) + return (ffs(val) - 1); + + return (0x3ff); +} + +void +pic_ipi_clear(int ipi) +{ + uint32_t val; + + val = ~(1 << ipi); + MPIC_CPU_WRITE(mv_mpic_sc, MPIC_IN_DOORBELL, val); +} + +#endif diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/mv_machdep.c armv6/sys/arm/mv/mv_machdep.c --- head/sys/arm/mv/mv_machdep.c 2012-08-08 18:48:36.403724204 -0700 +++ armv6/sys/arm/mv/mv_machdep.c 2012-08-12 18:33:11.234724667 -0700 @@ -122,14 +122,12 @@ extern vm_offset_t pmap_bootstrap_lastaddr; struct pv_addr kernel_pt_table[KERNEL_PT_MAX]; -struct pcpu __pcpu; -struct pcpu *pcpup = &__pcpu; /* Physical and virtual addresses for some global pages */ - vm_paddr_t phys_avail[10]; vm_paddr_t dump_avail[4]; vm_offset_t pmap_bootstrap_lastaddr; +vm_paddr_t pmap_pa; const struct pmap_devmap *pmap_devmap_bootstrap_table; struct pv_addr systempage; @@ -139,6 +137,8 @@ struct pv_addr abtstack; struct pv_addr kernelstack; +void set_stackptrs(int cpu); + static struct mem_region availmem_regions[FDT_MEM_REGIONS]; static int availmem_regions_sz; @@ -348,8 +348,7 @@ /* Platform-specific initialisation */ pmap_bootstrap_lastaddr = fdt_immr_va - ARM_NOCACHE_KVA_SIZE; - pcpu_init(pcpup, 0, sizeof(struct pcpu)); - PCPU_SET(curthread, &thread0); + pcpu0_init(); /* Calculate number of L2 tables needed for mapping vm_page_array */ l2size = (memsize / PAGE_SIZE) * sizeof(struct vm_page); @@ -407,10 +406,10 @@ dpcpu_init((void *)dpcpu.pv_va, 0); /* Allocate stacks for all modes */ - valloc_pages(irqstack, IRQ_STACK_SIZE); - valloc_pages(abtstack, ABT_STACK_SIZE); - valloc_pages(undstack, UND_STACK_SIZE); - valloc_pages(kernelstack, KSTACK_PAGES); + valloc_pages(irqstack, (IRQ_STACK_SIZE * MAXCPU)); + valloc_pages(abtstack, (ABT_STACK_SIZE * MAXCPU)); + valloc_pages(undstack, (UND_STACK_SIZE * MAXCPU)); + valloc_pages(kernelstack, (KSTACK_PAGES * MAXCPU)); init_param1(); @@ -462,7 +461,7 @@ pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH, &kernel_pt_table[l2size - 1]); pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa, - VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); + VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE, PTE_CACHE); /* Map pmap_devmap[] entries */ err_devmap = platform_devmap_init(); @@ -470,6 +469,7 @@ cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) | DOMAIN_CLIENT); + pmap_pa = kernel_l1pt.pv_pa; setttb(kernel_l1pt.pv_pa); cpu_tlb_flushID(); cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)); @@ -494,7 +494,7 @@ debugf("initarm: console initialized\n"); debugf(" arg1 kmdp = 0x%08x\n", (uint32_t)kmdp); debugf(" boothowto = 0x%08x\n", boothowto); - printf(" dtbp = 0x%08x\n", (uint32_t)dtbp); + debugf(" dtbp = 0x%08x\n", (uint32_t)dtbp); print_kernel_section_addr(); print_kenv(); @@ -505,9 +505,14 @@ /* * 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 /* * Pages were allocated during the secondary bootstrap for the @@ -518,12 +523,8 @@ * of the stack memory. */ cpu_control(CPU_CONTROL_MMU_ENABLE, CPU_CONTROL_MMU_ENABLE); - set_stackptr(PSR_IRQ32_MODE, - irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE); - set_stackptr(PSR_ABT32_MODE, - abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE); - set_stackptr(PSR_UND32_MODE, - undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE); + + set_stackptrs(0); /* * We must now clean the cache again.... @@ -564,7 +565,19 @@ sizeof(struct pcb))); } -#define MPP_PIN_MAX 50 +void +set_stackptrs(int cpu) +{ + + set_stackptr(PSR_IRQ32_MODE, + irqstack.pv_va + ((IRQ_STACK_SIZE * PAGE_SIZE) * (cpu + 1))); + set_stackptr(PSR_ABT32_MODE, + abtstack.pv_va + ((ABT_STACK_SIZE * PAGE_SIZE) * (cpu + 1))); + set_stackptr(PSR_UND32_MODE, + undstack.pv_va + ((UND_STACK_SIZE * PAGE_SIZE) * (cpu + 1))); +} + +#define MPP_PIN_MAX 68 #define MPP_PIN_CELLS 2 #define MPP_PINS_PER_REG 8 #define MPP_SEL(pin,func) (((func) & 0xf) << \ @@ -601,7 +614,11 @@ return (ENXIO); if ((node = fdt_find_compatible(node, "mrvl,mpp", 0)) == 0) - return (ENXIO); + /* + * 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. @@ -694,11 +711,49 @@ return (0); } -#define FDT_DEVMAP_MAX (MV_WIN_CPU_MAX + 1) +#define FDT_DEVMAP_MAX (MV_WIN_CPU_MAX + 2) static struct pmap_devmap fdt_devmap[FDT_DEVMAP_MAX] = { { 0, 0, 0, 0, 0, } }; +static int +platform_sram_devmap(struct pmap_devmap *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_NOCACHE; + + return (0); +out: +#endif + return (ENOENT); + +} + /* * XXX: When device entry in devmap has pd_size smaller than section size, * system will freeze during initialization @@ -730,27 +785,33 @@ 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")) { + 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) { + if (i + 1 >= FDT_DEVMAP_MAX) return (ENOMEM); - } /* * XXX this should account for PCI and multiple ranges * of a given kind. */ - if (fdt_pci_devmap(child, &fdt_devmap[i], - MV_PCIE_IO_BASE, MV_PCIE_MEM_BASE) != 0) + if (fdt_pci_devmap(child, &fdt_devmap[i], MV_PCI_VA_IO_BASE, + MV_PCI_VA_MEM_BASE) != 0) return (ENXIO); i += 2; } @@ -817,3 +878,62 @@ 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 */ + diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/mv_pci.c armv6/sys/arm/mv/mv_pci.c --- head/sys/arm/mv/mv_pci.c 2012-08-08 12:42:08.290723925 -0700 +++ armv6/sys/arm/mv/mv_pci.c 2012-08-12 19:16:37.966726085 -0700 @@ -240,16 +240,16 @@ parnode = OF_parent(node); if (fdt_is_compatible(node, "mrvl,pcie")) { sc->sc_type = MV_TYPE_PCIE; - sc->sc_mem_win_target = MV_WIN_PCIE_MEM_TARGET; - sc->sc_mem_win_attr = MV_WIN_PCIE_MEM_ATTR; - sc->sc_io_win_target = MV_WIN_PCIE_IO_TARGET; - sc->sc_io_win_attr = MV_WIN_PCIE_IO_ATTR; + sc->sc_mem_win_target = MV_WIN_PCIE_TARGET(0); + sc->sc_mem_win_attr = MV_WIN_PCIE_MEM_ATTR(0); + sc->sc_io_win_target = MV_WIN_PCIE_TARGET(0); + sc->sc_io_win_attr = MV_WIN_PCIE_IO_ATTR(0); #ifdef SOC_MV_ORION } else if (fdt_is_compatible(node, "mrvl,pci")) { sc->sc_type = MV_TYPE_PCI; - sc->sc_mem_win_target = MV_WIN_PCI_MEM_TARGET; + sc->sc_mem_win_target = MV_WIN_PCI_TARGET; sc->sc_mem_win_attr = MV_WIN_PCI_MEM_ATTR; - sc->sc_io_win_target = MV_WIN_PCI_IO_TARGET; + sc->sc_io_win_target = MV_WIN_PCI_TARGET; sc->sc_io_win_attr = MV_WIN_PCI_IO_ATTR; #endif } else diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/mvreg.h armv6/sys/arm/mv/mvreg.h --- head/sys/arm/mv/mvreg.h 2012-08-08 18:48:36.530281713 -0700 +++ armv6/sys/arm/mv/mvreg.h 2012-08-12 18:20:24.665728894 -0700 @@ -1,5 +1,5 @@ /*- - * Copyright (C) 2007-2008 MARVELL INTERNATIONAL LTD. + * Copyright (C) 2007-2011 MARVELL INTERNATIONAL LTD. * All rights reserved. * * Developed by Semihalf. @@ -34,9 +34,6 @@ #ifndef _MVREG_H_ #define _MVREG_H_ -#define BRIDGE_IRQ_CAUSE 0x10 -#define BRIGDE_IRQ_MASK 0x14 - #if defined(SOC_MV_DISCOVERY) #define IRQ_CAUSE_ERROR 0x0 #define IRQ_CAUSE 0x4 @@ -49,23 +46,55 @@ #define FIQ_MASK 0x20 #define FIQ_MASK_HI 0x24 #define FIQ_CAUSE_SELECT 0x28 -#define ENDPOINT_IRQ_MASK_ERROR 0x2C -#define ENDPOINT_IRQ_MASK 0x30 -#define ENDPOINT_IRQ_MASK_HI 0x34 +#define ENDPOINT_IRQ_MASK_ERROR(n) 0x2C +#define ENDPOINT_IRQ_MASK(n) 0x30 +#define ENDPOINT_IRQ_MASK_HI(n) 0x34 #define ENDPOINT_IRQ_CAUSE_SELECT 0x38 -#else /* !SOC_MV_DISCOVERY */ +#elif defined (SOC_MV_LOKIPLUS) || defined (SOC_MV_FREY) +#define IRQ_CAUSE 0x0 +#define IRQ_MASK 0x4 +#define FIQ_MASK 0x8 +#define ENDPOINT_IRQ_MASK(n) (0xC + (n) * 4) +#define IRQ_CAUSE_HI (-1) /* Fake defines for unified */ +#define IRQ_MASK_HI (-1) /* interrupt controller code */ +#define FIQ_MASK_HI (-1) +#define ENDPOINT_IRQ_MASK_HI(n) (-1) +#define ENDPOINT_IRQ_MASK_ERROR(n) (-1) +#define IRQ_CAUSE_ERROR (-1) +#define IRQ_MASK_ERROR (-1) +#elif defined (SOC_MV_ARMADAXP) +#define IRQ_CAUSE 0x18 +#define IRQ_MASK 0x30 +#else /* !SOC_MV_DISCOVERY && !SOC_MV_LOKIPLUS */ #define IRQ_CAUSE 0x0 #define IRQ_MASK 0x4 #define FIQ_MASK 0x8 -#define ENDPOINT_IRQ_MASK 0xC +#define ENDPOINT_IRQ_MASK(n) 0xC #define IRQ_CAUSE_HI 0x10 #define IRQ_MASK_HI 0x14 #define FIQ_MASK_HI 0x18 -#define ENDPOINT_IRQ_MASK_HI 0x1C +#define ENDPOINT_IRQ_MASK_HI(n) 0x1C +#define ENDPOINT_IRQ_MASK_ERROR(n) (-1) #define IRQ_CAUSE_ERROR (-1) /* Fake defines for unified */ #define IRQ_MASK_ERROR (-1) /* interrupt controller code */ #endif +#if defined(SOC_MV_FREY) +#define BRIDGE_IRQ_CAUSE 0x118 +#define IRQ_TIMER0 0x00000002 +#define IRQ_TIMER1 0x00000004 +#define IRQ_TIMER_WD 0x00000008 + +#define BRIDGE_IRQ_MASK 0x11c +#define IRQ_TIMER0_MASK 0x00000002 +#define IRQ_TIMER1_MASK 0x00000004 +#define IRQ_TIMER_WD_MASK 0x00000008 +#elif defined(SOC_MV_ARMADAXP) +#define BRIDGE_IRQ_CAUSE 0x68 +#define IRQ_TIMER0 0x00000001 +#define IRQ_TIMER1 0x00000002 +#define IRQ_TIMER_WD 0x00000004 +#else #define BRIDGE_IRQ_CAUSE 0x10 #define IRQ_CPU_SELF 0x00000001 #define IRQ_TIMER0 0x00000002 @@ -77,6 +106,19 @@ #define IRQ_TIMER0_MASK 0x00000002 #define IRQ_TIMER1_MASK 0x00000004 #define IRQ_TIMER_WD_MASK 0x00000008 +#endif + +#if defined(SOC_MV_LOKIPLUS) || defined(SOC_MV_FREY) +#define IRQ_CPU_SELF_CLR IRQ_CPU_SELF +#define IRQ_TIMER0_CLR IRQ_TIMER0 +#define IRQ_TIMER1_CLR IRQ_TIMER1 +#define IRQ_TIMER_WD_CLR IRQ_TIMER_WD +#else +#define IRQ_CPU_SELF_CLR (~IRQ_CPU_SELF) +#define IRQ_TIMER0_CLR (~IRQ_TIMER0) +#define IRQ_TIMER1_CLR (~IRQ_TIMER1) +#define IRQ_TIMER_WD_CLR (~IRQ_TIMER_WD) +#endif /* * System reset @@ -155,6 +197,7 @@ /* * Timers */ +#define CPU_TIMERS_BASE 0x300 #define CPU_TIMER_CONTROL 0x0 #define CPU_TIMER0_EN 0x00000001 #define CPU_TIMER0_AUTO 0x00000002 @@ -182,7 +225,15 @@ #define SATA_CR_NOPRDPBS (1 << 10) #define SATA_CR_COALDIS(ch) (1 << (24 + ch)) -#define SATA_ICR 0x014 /* Interrupt Cause Reg. */ +/* Interrupt Coalescing Threshold Reg. */ +#define SATA_ICTR 0x00C +#define SATA_ICTR_MAX ((1 << 8) - 1) + +/* Interrupt Time Threshold Reg. */ +#define SATA_ITTR 0x010 +#define SATA_ITTR_MAX ((1 << 24) - 1) + +#define SATA_ICR 0x014 /* Interrupt Cause Reg. */ #define SATA_ICR_DMADONE(ch) (1 << (ch)) #define SATA_ICR_COAL (1 << 4) #define SATA_ICR_DEV(ch) (1 << (8 + ch)) @@ -271,34 +322,18 @@ #define GPIO2IRQ(gpio) ((gpio) + NIRQ) #define IRQ2GPIO(irq) ((irq) - NIRQ) -/* - * MPP - */ -#if defined(SOC_MV_ORION) -#define MPP_CONTROL0 0x00 -#define MPP_CONTROL1 0x04 -#define MPP_CONTROL2 0x50 -#elif defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY) -#define MPP_CONTROL0 0x00 -#define MPP_CONTROL1 0x04 -#define MPP_CONTROL2 0x08 -#define MPP_CONTROL3 0x0C -#define MPP_CONTROL4 0x10 -#define MPP_CONTROL5 0x14 -#define MPP_CONTROL6 0x18 -#else -#error SOC_MV_XX not defined -#endif - -#if defined(SOC_MV_ORION) +#if defined(SOC_MV_ORION) || defined(SOC_MV_LOKIPLUS) #define SAMPLE_AT_RESET 0x10 #elif defined(SOC_MV_KIRKWOOD) #define SAMPLE_AT_RESET 0x30 #elif defined(SOC_MV_DISCOVERY) #define SAMPLE_AT_RESET_LO 0x30 #define SAMPLE_AT_RESET_HI 0x34 -#else -#error SOC_MV_XX not defined +#elif defined(SOC_MV_DOVE) +#define SAMPLE_AT_RESET_LO 0x14 +#define SAMPLE_AT_RESET_HI 0x18 +#elif defined(SOC_MV_FREY) +#define SAMPLE_AT_RESET 0x100 #endif /* @@ -310,6 +345,9 @@ #elif defined(SOC_MV_DISCOVERY) #define TCLK_MASK 0x00000180 #define TCLK_SHIFT 0x07 +#elif defined(SOC_MV_LOKIPLUS) +#define TCLK_MASK 0x0000F000 +#define TCLK_SHIFT 0x0C #endif #define TCLK_100MHZ 100000000 @@ -318,6 +356,33 @@ #define TCLK_150MHZ 150000000 #define TCLK_166MHZ 166666667 #define TCLK_200MHZ 200000000 +#define TCLK_250MHZ 250000000 +#define TCLK_300MHZ 300000000 +#define TCLK_667MHZ 667000000 + +/* + * CPU Cache Configuration + */ + +#define CPU_CONFIG 0x00000000 +#define CPU_CONFIG_IC_PREF 0x00010000 +#define CPU_CONFIG_DC_PREF 0x00020000 +#define CPU_CONTROL 0x00000004 +#define CPU_CONTROL_L2_SIZE 0x00200000 /* Only on Discovery */ +#define CPU_CONTROL_L2_MODE 0x00020000 /* Only on Discovery */ +#define CPU_L2_CONFIG 0x00000028 /* Only on Kirkwood */ +#define CPU_L2_CONFIG_MODE 0x00000010 /* Only on Kirkwood */ + +/* + * PCI Express port control (CPU Control registers) + */ +#define CPU_CONTROL_PCIE_DISABLE(n) (1 << (3 * (n))) + +/* + * Vendor ID + */ +#define PCI_VENDORID_MRVL 0x11AB +#define PCI_VENDORID_MRVL2 0x1B4B /* * Chip ID @@ -326,8 +391,35 @@ #define MV_DEV_88F5182 0x5182 #define MV_DEV_88F5281 0x5281 #define MV_DEV_88F6281 0x6281 +#define MV_DEV_88F6781 0x6781 #define MV_DEV_88F6282 0x6282 #define MV_DEV_MV78100_Z0 0x6381 #define MV_DEV_MV78100 0x7810 +#define MV_DEV_MV78130 0x7813 +#define MV_DEV_MV78160 0x7816 +#define MV_DEV_MV78230 0x7823 +#define MV_DEV_MV78260 0x7826 +#define MV_DEV_MV78460 0x7846 +#define MV_DEV_88RC8180 0x8180 +#define MV_DEV_88RC9480 0x9480 +#define MV_DEV_88RC9580 0x9580 + +#define MV_DEV_FAMILY_MASK 0xff00 +#define MV_DEV_DISCOVERY 0x7800 +/* + * Doorbell register control + */ +#define MV_DRBL_PCIE_TO_CPU 0 +#define MV_DRBL_CPU_TO_PCIE 1 + +#if defined(SOC_MV_FREY) +#define MV_DRBL_CAUSE(d,u) (0x60 + 0x20 * (d) + 0x8 * (u)) +#define MV_DRBL_MASK(d,u) (0x60 + 0x20 * (d) + 0x8 * (u) + 0x4) +#define MV_DRBL_MSG(m,d,u) (0x8 * (u) + 0x20 * (d) + 0x4 * (m)) +#else +#define MV_DRBL_CAUSE(d,u) (0x10 * (u) + 0x8 * (d)) +#define MV_DRBL_MASK(d,u) (0x10 * (u) + 0x8 * (d) + 0x4) +#define MV_DRBL_MSG(m,d,u) (0x10 * (u) + 0x8 * (d) + 0x4 * (m) + 0x30) +#endif #endif /* _MVREG_H_ */ diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/mvvar.h armv6/sys/arm/mv/mvvar.h --- head/sys/arm/mv/mvvar.h 2012-08-10 15:17:26.983890206 -0700 +++ armv6/sys/arm/mv/mvvar.h 2012-08-08 12:43:44.475723819 -0700 @@ -41,6 +41,7 @@ #define _MVVAR_H_ #include +#include #include #include #include @@ -49,6 +50,9 @@ #define MV_TYPE_PCI 0 #define MV_TYPE_PCIE 1 +#define MV_MODE_ENDPOINT 0 +#define MV_MODE_ROOT 1 + struct gpio_config { int gc_gpio; /* GPIO number */ uint32_t gc_flags; /* GPIO flags */ @@ -60,11 +64,12 @@ int attr; /* Attributes of the target interface */ vm_paddr_t base; /* Physical base addr */ uint32_t size; - int remap; + vm_paddr_t remap; }; extern const struct pmap_devmap pmap_devmap[]; extern const struct gpio_config mv_gpio_config[]; +extern const struct decode_win *cpu_wins; extern const struct decode_win *idma_wins; extern const struct decode_win *xor_wins; extern int idma_wins_no; @@ -86,9 +91,10 @@ void soc_power_ctrl_set(uint32_t mask); int decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size, - int remap); + vm_paddr_t remap); int decode_win_overlap(int, int, const struct decode_win *); int win_cpu_can_remap(int); +void decode_win_pcie_setup(u_long); int ddr_is_active(int i); uint32_t ddr_base(int i); @@ -98,7 +104,26 @@ uint32_t cpu_extra_feat(void); uint32_t get_tclk(void); +uint32_t get_l2clk(void); uint32_t read_cpu_ctrl(uint32_t); void write_cpu_ctrl(uint32_t, uint32_t); +int mv_pcib_bar_win_set(device_t dev, uint32_t base, uint32_t size, + uint32_t remap, int winno, int busno); +int mv_pcib_cpu_win_remap(device_t dev, uint32_t remap, uint32_t size); + +void mv_mask_endpoint_irq(uintptr_t nb, int unit); +void mv_unmask_endpoint_irq(uintptr_t nb, int unit); + +int mv_drbl_get_next_irq(int dir, int unit); +void mv_drbl_mask_all(int unit); +void mv_drbl_mask_irq(uint32_t irq, int dir, int unit); +void mv_drbl_unmask_irq(uint32_t irq, int dir, int unit); +void mv_drbl_set_mask(uint32_t val, int dir, int unit); +uint32_t mv_drbl_get_mask(int dir, int unit); +void mv_drbl_set_cause(uint32_t val, int dir, int unit); +uint32_t mv_drbl_get_cause(int dir, int unit); +void mv_drbl_set_msg(uint32_t val, int mnr, int dir, int unit); +uint32_t mv_drbl_get_msg(int mnr, int dir, int unit); + #endif /* _MVVAR_H_ */ diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/mvwin.h armv6/sys/arm/mv/mvwin.h --- head/sys/arm/mv/mvwin.h 2012-08-08 17:36:36.037724601 -0700 +++ armv6/sys/arm/mv/mvwin.h 2012-08-12 19:16:37.969174466 -0700 @@ -1,5 +1,5 @@ /*- - * Copyright (C) 2007-2008 MARVELL INTERNATIONAL LTD. + * Copyright (C) 2007-2011 MARVELL INTERNATIONAL LTD. * All rights reserved. * * Developed by Semihalf. @@ -35,64 +35,118 @@ #define _MVWIN_H_ /* - * Physical addresses of integrated SoC peripherals + * 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 0x100000 +#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 /* - * Decode windows addresses (physical) + * External devices: 0x80000000, 1 GB (VA == PA) + * Includes Device Bus, PCI and PCIE. */ -#define MV_PCIE_IO_PHYS_BASE (MV_PHYS_BASE + MV_SIZE) -#define MV_PCIE_IO_BASE MV_PCIE_IO_PHYS_BASE -#define MV_PCIE_IO_SIZE (1024 * 1024) -#define MV_PCI_IO_PHYS_BASE (MV_PCIE_IO_PHYS_BASE + MV_PCIE_IO_SIZE) -#define MV_PCI_IO_BASE MV_PCI_IO_PHYS_BASE -#define MV_PCI_IO_SIZE (1024 * 1024) +#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 */ +#else +#error "MV_PCI_PORTS not configured !" +#endif -#define MV_PCIE_MEM_PHYS_BASE (MV_PCI_IO_PHYS_BASE + MV_PCI_IO_SIZE) -#define MV_PCIE_MEM_BASE MV_PCIE_MEM_PHYS_BASE -#define MV_PCIE_MEM_SIZE (64 * 1024 * 1024) -#define MV_PCI_MEM_PHYS_BASE (MV_PCIE_MEM_PHYS_BASE + MV_PCIE_MEM_SIZE) +/* 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_SIZE (64 * 1024 * 1024) +#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)) -#define MV_DEV_BOOT_BASE 0xF9300000 -#define MV_DEV_BOOT_SIZE (1024 * 1024) /* 1 MB */ +#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 -#define MV_DEV_CS0_BASE 0xF9400000 -#define MV_DEV_CS0_SIZE (1024 * 1024) /* 1 MB */ +/* + * Device Bus (VA == PA) + */ +#define MV_DEV_BOOT_BASE 0xF9300000 +#define MV_DEV_BOOT_SIZE (1024 * 1024) /* 1 MB */ -#define MV_DEV_CS1_BASE 0xF9500000 -#define MV_DEV_CS1_SIZE (32 * 1024 * 1024) /* 32 MB */ +#define MV_DEV_CS0_BASE 0xF9400000 +#define MV_DEV_CS0_SIZE (1024 * 1024) /* 1 MB */ -#define MV_DEV_CS2_BASE 0xFB500000 -#define MV_DEV_CS2_SIZE (1024 * 1024) /* 1 MB */ +#define MV_DEV_CS1_BASE 0xF9500000 +#define MV_DEV_CS1_SIZE (32 * 1024 * 1024) /* 32 MB */ -#define MV_CESA_SRAM_PHYS_BASE 0xFD000000 -#define MV_CESA_SRAM_BASE MV_CESA_SRAM_PHYS_BASE /* VA == PA mapping */ -#define MV_CESA_SRAM_SIZE (1024 * 1024) +#define MV_DEV_CS2_BASE 0xFB500000 +#define MV_DEV_CS2_SIZE (1024 * 1024) /* 1 MB */ -/* XXX this is probably not robust against wraparounds... */ -#if ((MV_CESA_SRAM_PHYS_BASE + MV_CESA_SRAM_SIZE) > 0xFFFEFFFF) -#error Devices memory layout overlaps reset vectors range! -#endif /* * 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) +#else #define MV_DDR_CADR_BASE (MV_BASE + 0x1500) +#endif #define MV_MPP_BASE (MV_BASE + 0x10000) +#if defined(SOC_MV_ARMADAXP) +#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 + 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) +#else #define MV_PCIE_BASE (MV_BASE + 0x40000) +#endif #define MV_PCIE_SIZE 0x2000 #define MV_PCIE00_BASE (MV_PCIE_BASE + 0x00000) @@ -104,22 +158,53 @@ #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) +#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) +#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 */ #define MV_WIN_CESA_CTRL(n) (0x8 * (n) + 0xa04) #define MV_WIN_CESA_BASE(n) (0x8 * (n) + 0xa00) @@ -133,8 +218,8 @@ #define MV_WIN_CESA_ATTR 0 #endif -#define MV_WIN_USB_CTRL(n) (0x10 * (n) + 0x0) -#define MV_WIN_USB_BASE(n) (0x10 * (n) + 0x4) +#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) @@ -158,25 +243,25 @@ #define MV_XOR_CHAN_MAX 2 #define MV_XOR_NON_REMAP 4 -#if defined(SOC_MV_DISCOVERY) -#define MV_WIN_PCIE_MEM_TARGET 4 -#define MV_WIN_PCIE_MEM_ATTR 0xE8 -#define MV_WIN_PCIE_IO_TARGET 4 -#define MV_WIN_PCIE_IO_ATTR 0xE0 -#elif defined(SOC_MV_KIRKWOOD) -#define MV_WIN_PCIE_MEM_TARGET 4 -#define MV_WIN_PCIE_MEM_ATTR 0xE8 -#define MV_WIN_PCIE_IO_TARGET 4 -#define MV_WIN_PCIE_IO_ATTR 0xE0 +#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_ORION) -#define MV_WIN_PCIE_MEM_TARGET 4 -#define MV_WIN_PCIE_MEM_ATTR 0x59 -#define MV_WIN_PCIE_IO_TARGET 4 -#define MV_WIN_PCIE_IO_ATTR 0x51 -#define MV_WIN_PCI_MEM_TARGET 3 +#define MV_WIN_PCIE_TARGET(n) 4 +#define MV_WIN_PCIE_MEM_ATTR(n) 0x59 +#define MV_WIN_PCIE_IO_ATTR(n) 0x51 +#define MV_WIN_PCI_TARGET 3 #define MV_WIN_PCI_MEM_ATTR 0x59 -#define MV_WIN_PCI_IO_TARGET 3 #define MV_WIN_PCI_IO_ATTR 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_PCIE_CTRL(n) (0x10 * (((n) < 5) ? (n) : \ @@ -187,8 +272,15 @@ (n) + 1) + 0x182C) #define MV_WIN_PCIE_MAX 6 -#define MV_PCIE_BAR(n) (0x04 * (n) + 0x1804) -#define MV_PCIE_BAR_MAX 3 +#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) diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/orion/files.db88f5xxx armv6/sys/arm/mv/orion/files.db88f5xxx --- head/sys/arm/mv/orion/files.db88f5xxx 2012-08-08 12:42:08.257723993 -0700 +++ armv6/sys/arm/mv/orion/files.db88f5xxx 2012-08-12 18:14:01.026725763 -0700 @@ -1,4 +1,5 @@ -# $FreeBSD: head/sys/arm/mv/orion/files.db88f5xxx 183840 2008-10-13 20:07:13Z raj $ +# $FreeBSD: projects/armv6/sys/arm/mv/orion/files.db88f5xxx 239223 2012-08-13 01:14:00Z gonzo $ +arm/mv/ic.c standard arm/mv/orion/orion.c standard arm/mv/orion/db88f5xxx.c standard diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/orion/files.ts7800 armv6/sys/arm/mv/orion/files.ts7800 --- head/sys/arm/mv/orion/files.ts7800 2012-08-08 12:42:08.254723924 -0700 +++ armv6/sys/arm/mv/orion/files.ts7800 2012-08-12 18:14:01.027724761 -0700 @@ -1,4 +1,5 @@ -# $FreeBSD: head/sys/arm/mv/orion/files.ts7800 220653 2011-04-15 13:37:43Z philip $ +# $FreeBSD: projects/armv6/sys/arm/mv/orion/files.ts7800 239223 2012-08-13 01:14:00Z gonzo $ +arm/mv/ic.c standard arm/mv/orion/orion.c standard diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/std-pj4b.mv armv6/sys/arm/mv/std-pj4b.mv --- head/sys/arm/mv/std-pj4b.mv 1969-12-31 16:00:00.000000000 -0800 +++ armv6/sys/arm/mv/std-pj4b.mv 2012-08-08 12:43:45.605723704 -0700 @@ -0,0 +1,6 @@ +# $FreeBSD: src/sys/arm/mv/std.mv,v 1.1 2008/10/13 20:07:13 raj Exp $ + +files "../mv/files.mv" +cpu CPU_MV_PJ4B + +options VM_MAXUSER_ADDRESS="(KERNBASE-(1024*1024*1024))" diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/arm/mv/timer.c armv6/sys/arm/mv/timer.c --- head/sys/arm/mv/timer.c 2012-08-08 12:42:08.291723973 -0700 +++ armv6/sys/arm/mv/timer.c 2012-08-08 12:43:45.230724623 -0700 @@ -55,6 +55,12 @@ #define INITIAL_TIMECOUNTER (0xffffffff) #define MAX_WATCHDOG_TICKS (0xffffffff) +#if defined(SOC_MV_ARMADAXP) +#define MV_CLOCK_SRC get_l2clk() +#else +#define MV_CLOCK_SRC get_tclk() +#endif + struct mv_timer_softc { struct resource * timer_res[2]; bus_space_tag_t timer_bst; @@ -116,7 +122,9 @@ int error; void *ihl; struct mv_timer_softc *sc; +#if !defined(SOC_MV_ARMADAXP) uint32_t irq_cause, irq_mask; +#endif if (timer_softc != NULL) return (ENXIO); @@ -145,18 +153,21 @@ } mv_setup_timers(); +#if !defined(SOC_MV_ARMADAXP) irq_cause = read_cpu_ctrl(BRIDGE_IRQ_CAUSE); - irq_cause &= ~(IRQ_TIMER0); + irq_cause &= IRQ_TIMER0_CLR; + write_cpu_ctrl(BRIDGE_IRQ_CAUSE, irq_cause); irq_mask = read_cpu_ctrl(BRIDGE_IRQ_MASK); irq_mask |= IRQ_TIMER0_MASK; irq_mask &= ~IRQ_TIMER1_MASK; write_cpu_ctrl(BRIDGE_IRQ_MASK, irq_mask); - +#endif sc->et.et_name = "CPUTimer0"; sc->et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT; sc->et.et_quality = 1000; - sc->et.et_frequency = get_tclk(); + + sc->et.et_frequency = MV_CLOCK_SRC; sc->et.et_min_period.sec = 0; sc->et.et_min_period.frac = ((0x00000002LLU << 32) / sc->et.et_frequency) << 32; @@ -167,7 +178,7 @@ sc->et.et_stop = mv_timer_stop; sc->et.et_priv = sc; et_register(&sc->et); - mv_timer_timecounter.tc_frequency = get_tclk(); + mv_timer_timecounter.tc_frequency = MV_CLOCK_SRC; tc_init(&mv_timer_timecounter); return (0); @@ -180,7 +191,7 @@ uint32_t irq_cause; irq_cause = read_cpu_ctrl(BRIDGE_IRQ_CAUSE); - irq_cause &= ~(IRQ_TIMER0); + irq_cause &= IRQ_TIMER0_CLR; write_cpu_ctrl(BRIDGE_IRQ_CAUSE, irq_cause); sc = (struct mv_timer_softc *)arg; @@ -235,7 +246,7 @@ } val = mv_get_timer(1); - nticks = ((get_tclk() / 1000000 + 1) * usec); + nticks = ((MV_CLOCK_SRC / 1000000 + 1) * usec); while (nticks > 0) { val_temp = mv_get_timer(1); @@ -291,16 +302,20 @@ static void mv_watchdog_enable(void) { - uint32_t val; - uint32_t irq_cause, irq_mask; + uint32_t val, irq_cause; +#if !defined(SOC_MV_ARMADAXP) + uint32_t irq_mask; +#endif irq_cause = read_cpu_ctrl(BRIDGE_IRQ_CAUSE); - irq_cause &= ~(IRQ_TIMER_WD); + irq_cause &= IRQ_TIMER_WD_CLR; write_cpu_ctrl(BRIDGE_IRQ_CAUSE, irq_cause); +#if !defined(SOC_MV_ARMADAXP) irq_mask = read_cpu_ctrl(BRIDGE_IRQ_MASK); irq_mask |= IRQ_TIMER_WD_MASK; write_cpu_ctrl(BRIDGE_IRQ_MASK, irq_mask); +#endif val = read_cpu_ctrl(RSTOUTn_MASK); val |= WD_RST_OUT_EN; @@ -314,8 +329,10 @@ static void mv_watchdog_disable(void) { - uint32_t val; - uint32_t irq_cause, irq_mask; + uint32_t val, irq_cause; +#if !defined(SOC_MV_ARMADAXP) + uint32_t irq_mask; +#endif val = mv_get_timer_control(); val &= ~(CPU_TIMER_WD_EN | CPU_TIMER_WD_AUTO); @@ -325,12 +342,14 @@ val &= ~WD_RST_OUT_EN; write_cpu_ctrl(RSTOUTn_MASK, val); +#if !defined(SOC_MV_ARMADAXP) irq_mask = read_cpu_ctrl(BRIDGE_IRQ_MASK); irq_mask &= ~(IRQ_TIMER_WD_MASK); write_cpu_ctrl(BRIDGE_IRQ_MASK, irq_mask); +#endif irq_cause = read_cpu_ctrl(BRIDGE_IRQ_CAUSE); - irq_cause &= ~(IRQ_TIMER_WD); + irq_cause &= IRQ_TIMER_WD_CLR; write_cpu_ctrl(BRIDGE_IRQ_CAUSE, irq_cause); } @@ -353,7 +372,7 @@ * watchdog(9) */ ns = (uint64_t)1 << (cmd & WD_INTERVAL); - ticks = (uint64_t)(ns * get_tclk()) / 1000000000; + ticks = (uint64_t)(ns * MV_CLOCK_SRC) / 1000000000; if (ticks > MAX_WATCHDOG_TICKS) mv_watchdog_disable(); else { diff -x .svn -I '$FreeBSD.*$' -Naur head/sys/boot/fdt/dts/db88f78160.dts armv6/sys/boot/fdt/dts/db88f78160.dts --- head/sys/boot/fdt/dts/db88f78160.dts 1969-12-31 16:00:00.000000000 -0800 +++ armv6/sys/boot/fdt/dts/db88f78160.dts 2012-08-08 12:44:04.350723836 -0700 @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2010 The FreeBSD Foundation + * Copyright (c) 2010-2011 Semihalf + * 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. + * + * Marvell DB-88F78160 Device Tree Source. + * + */ + +/dts-v1/; + +/ { + model = "mrvl,DB-78160"; + #address-cells = <1>; + #size-cells = <1>; + + aliases { + serial0 = &serial0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "ARM,88VS584"; + reg = <0x0>; + d-cache-line-size = <32>; // 32 bytes + i-cache-line-size = <32>; // 32 bytes + d-cache-size = <0x8000>; // L1, 32K + i-cache-size = <0x8000>; // L1, 32K + timebase-frequency = <0>; + bus-frequency = <200000000>; + clock-frequency = <0>; + }; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x40000000>; // 2G at 0x0 + }; + + soc78160@d0000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges = <0x0 0xd0000000 0x00100000>; + bus-frequency = <0>; + + + MPIC: mpic@20a00 { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + reg = <0x20a00 0x500 0x21000 0x800>; + compatible = "mrvl,mpic"; + }; + + rtc@10300 { + compatible = "mrvl,rtc"; + reg = <0x10300 0x08>; + }; + + timer@21840 { + compatible = "mrvl,timer"; + reg = <0x21840 0x30>; + interrupts = <5>; + interrupt-parent = <&MPIC>; + mrvl,has-wdt; + }; + + twsi@11000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mrvl,twsi"; + reg = <0x11000 0x20>; + interrupts = <31>; + interrupt-parent = <&MPIC>; + }; + + twsi@11100 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mrvl,twsi"; + reg = <0x11100 0x20>; + interrupts = <32>; + interrupt-parent = <&MPIC>; + }; + + serial0: serial@12000 { + compatible = "ns16550"; + reg = <0x12000 0x20>; + reg-shift = <2>; + current-speed = <115200>; + clock-frequency = <200000000>; + interrupts = <41>; + interrupt-parent = <&MPIC>; + }; + + serial1: serial@12100 { + compatible = "ns16550"; + reg = <0x12100 0x20>; + reg-shift = <2>; + current-speed = <115200>; + clock-frequency = <200000000>; + interrupts = <42>; + interrupt-parent = <&MPIC>; + }; + + serial2: serial@12200 { + compatible = "ns16550"; + reg = <0x12200 0x20>; + reg-shift = <2>; + current-speed = <115200>; + clock-frequency = <200000000>; + interrupts = <43>; + interrupt-parent = <&MPIC>; + }; + + serial3: serial@12300 { + compatible = "ns16550"; + reg = <0x12300 0x20>; + reg-shift = <2>; + current-speed = <115200>; + clock-frequency = <200000000>; + interrupts = <44>; + interrupt-parent = <&MPIC>; + }; + + MPP: mpp@10000 { + #pin-cells = <2>; + compatible = "mrvl,mpp"; + reg = <0x18000 0x34>; + pin-count = <68>; + pin-map = < + 0 1 /* MPP[0]: GE1_TXCLK */ + 1 1 /* MPP[1]: GE1_TXCTL */ + 2 1 /* MPP[2]: GE1_RXCTL */ + 3 1 /* MPP[3]: GE1_RXCLK */ + 4 1 /* MPP[4]: GE1_TXD[0] */ + 5 1 /* MPP[5]: GE1_TXD[1] */ + 6 1 /* MPP[6]: GE1_TXD[2] */ + 7 1 /* MPP[7]: GE1_TXD[3] */ + 8 1 /* MPP[8]: GE1_RXD[0] */ + 9 1 /* MPP[9]: GE1_RXD[1] */ + 10 1 /* MPP[10]: GE1_RXD[2] */ + 11 1 /* MPP[11]: GE1_RXD[3] */ + 12 2 /* MPP[13]: SYSRST_OUTn */ + 13 2 /* MPP[13]: SYSRST_OUTn */ + 14 2 /* MPP[14]: SATA1_ACTn */ + 15 2 /* MPP[15]: SATA0_ACTn */ + 16 2 /* MPP[16]: UA2_TXD */ + 17 2 /* MPP[17]: UA2_RXD */ + 18 2 /* MPP[18]: */ + 19 2 /* MPP[19]: */ + 20 2 /* MPP[20]: */ + 21 2 /* MPP[21]: */ + 22 2 /* MPP[22]: UA3_TXD */ + 23 2 + 24 0 + 25 0 + 26 0 + 27 0 + 28 4 + 29 0 + 30 1 + 31 1 + 32 1 + 33 1 + 34 1 + 35 1 + 36 1 + 37 1 + 38 1 + 39 1 + 40 0 + 41 3 + 42 1 + 43 1 + 44 2 + 45 2 + 46 4 + 47 3 + 48 0 + 49 1 + 50 1 + 51 1 + 52 1 + 53 1 + 54 1 + 55 1 + 56 1 + 57 0 + 58 1 + 59 1 + 60 1 + 61 1 + 62 1 + 63 1 + 64 1 + 65 1 + 66 1 + 67 2 >; + }; + + usb@50000 { + compatible = "mrvl,usb-ehci", "usb-ehci"; + reg = <0x50000 0x1000>; + interrupts = <124 45>; + interrupt-parent = <&MPIC>; + }; + + usb@51000 { + compatible = "mrvl,usb-ehci", "usb-ehci"; + reg = <0x51000 0x1000>; + interrupts = <124 46>; + interrupt-parent = <&MPIC>; + }; + + usb@52000 { + compatible = "mrvl,usb-ehci", "usb-ehci"; + reg = <0x52000 0x1000>; + interrupts = <124 47>; + interrupt-parent = <&MPIC>; + }; + + enet0: ethernet@72000 { + #address-cells = <1>; + #size-cells = <1>; + model = "V2"; + compatible = "mrvl,ge"; + reg = <0x72000 0x2000>; + ranges = <0x0 0x72000 0x2000>; + local-mac-address = [ 00 04 01 07 84 60 ]; + interrupts = <67 68 122 >; + interrupt-parent = <&MPIC>; + phy-handle = <&phy0>; + has-neta; + + mdio@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mrvl,mdio"; + + phy0: ethernet-phy@0 { + reg = <0x0>; + }; + phy1: ethernet-phy@1 { + reg = <0x1>; + }; + phy2: ethernet-phy@2 { + reg = <0x19>; + }; + phy3: ethernet-phy@3 { + reg = <0x1b>; + }; + }; + }; + }; + + pci0: pcie@f1040000 { + compatible = "mrvl,pcie"; + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <0xf1040000 0x2000>; + bus-range = <0 255>; + ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000 + 0x01000000 0x0 0x00000000 0xa0000000 0x0 0x08000000>; + clock-frequency = <33333333>; + interrupt-parent = <&MPIC>; + interrupts = <58>; + interrupt-map-mask = <0xf800 0x0 0x0 0x7>; + interrupt-map = < + 0x0800 0x0 0x0 0x1 &MPIC 0x20 + 0x0800 0x0 0x0 0x2 &MPIC 0x21 + 0x0800 0x0 0x0 0x3 &MPIC 0x22 + 0x0800 0x0 0x0 0x4 &MPIC 0x23 + >; + }; + + chosen { + stdin = "serial0"; + stdout = "serial0"; + stddbg = "serial0"; + }; +};