Merge branch 'pm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspe...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 29 Oct 2010 22:09:56 +0000 (15:09 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 29 Oct 2010 22:09:56 +0000 (15:09 -0700)
* 'pm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6:
  PM / Runtime: Fix typo in status comparison causing warning

420 files changed:
Documentation/DocBook/kgdb.tmpl
Makefile
arch/arm/include/asm/kgdb.h
arch/arm/kernel/kgdb.c
arch/blackfin/kernel/kgdb.c
arch/ia64/kernel/perfmon.c
arch/mips/Kconfig
arch/mips/Kconfig.debug
arch/mips/Makefile
arch/mips/ar7/gpio.c
arch/mips/ar7/platform.c
arch/mips/ar7/prom.c
arch/mips/ar7/setup.c
arch/mips/bcm63xx/cpu.c
arch/mips/cavium-octeon/Kconfig
arch/mips/cavium-octeon/csrc-octeon.c
arch/mips/cavium-octeon/dma-octeon.c
arch/mips/cavium-octeon/executive/cvmx-l2c.c
arch/mips/cavium-octeon/octeon-platform.c
arch/mips/cavium-octeon/serial.c
arch/mips/cavium-octeon/setup.c
arch/mips/include/asm/atomic.h
arch/mips/include/asm/bitops.h
arch/mips/include/asm/bootinfo.h
arch/mips/include/asm/cmpxchg.h
arch/mips/include/asm/cpu.h
arch/mips/include/asm/device.h
arch/mips/include/asm/dma-mapping.h
arch/mips/include/asm/dma.h
arch/mips/include/asm/local.h
arch/mips/include/asm/mach-ar7/ar7.h
arch/mips/include/asm/mach-ar7/gpio.h
arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
arch/mips/include/asm/mach-ip27/dma-coherence.h
arch/mips/include/asm/mach-ip32/dma-coherence.h
arch/mips/include/asm/mach-jazz/dma-coherence.h
arch/mips/include/asm/mipsregs.h
arch/mips/include/asm/octeon/cvmx-agl-defs.h
arch/mips/include/asm/octeon/cvmx-asm.h
arch/mips/include/asm/octeon/cvmx-ciu-defs.h
arch/mips/include/asm/octeon/cvmx-gpio-defs.h
arch/mips/include/asm/octeon/cvmx-iob-defs.h
arch/mips/include/asm/octeon/cvmx-ipd-defs.h
arch/mips/include/asm/octeon/cvmx-l2c-defs.h
arch/mips/include/asm/octeon/cvmx-l2c.h
arch/mips/include/asm/octeon/cvmx-l2d-defs.h
arch/mips/include/asm/octeon/cvmx-l2t-defs.h
arch/mips/include/asm/octeon/cvmx-led-defs.h
arch/mips/include/asm/octeon/cvmx-mio-defs.h
arch/mips/include/asm/octeon/cvmx-mixx-defs.h
arch/mips/include/asm/octeon/cvmx-npei-defs.h
arch/mips/include/asm/octeon/cvmx-npi-defs.h
arch/mips/include/asm/octeon/cvmx-pci-defs.h
arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
arch/mips/include/asm/octeon/cvmx-pescx-defs.h
arch/mips/include/asm/octeon/cvmx-pexp-defs.h
arch/mips/include/asm/octeon/cvmx-pow-defs.h
arch/mips/include/asm/octeon/cvmx-rnm-defs.h
arch/mips/include/asm/octeon/cvmx-smix-defs.h
arch/mips/include/asm/octeon/cvmx-uctlx-defs.h [new file with mode: 0644]
arch/mips/include/asm/octeon/octeon-model.h
arch/mips/include/asm/octeon/octeon.h
arch/mips/include/asm/octeon/pci-octeon.h
arch/mips/include/asm/perf_event.h [new file with mode: 0644]
arch/mips/include/asm/pgtable-64.h
arch/mips/include/asm/processor.h
arch/mips/include/asm/system.h
arch/mips/include/asm/thread_info.h
arch/mips/include/asm/uaccess.h
arch/mips/kernel/Makefile
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/irq.c
arch/mips/kernel/perf_event.c [new file with mode: 0644]
arch/mips/kernel/perf_event_mipsxx.c [new file with mode: 0644]
arch/mips/kernel/setup.c
arch/mips/kernel/traps.c
arch/mips/kernel/unaligned.c
arch/mips/loongson/Kconfig
arch/mips/math-emu/cp1emu.c
arch/mips/mm/c-octeon.c
arch/mips/mm/c-r4k.c
arch/mips/mm/dma-default.c
arch/mips/mm/fault.c
arch/mips/mm/sc-mips.c
arch/mips/mm/tlbex.c
arch/mips/mm/uasm.c
arch/mips/pci/pci-octeon.c
arch/mips/pci/pcie-octeon.c
arch/powerpc/include/asm/kgdb.h
arch/powerpc/kernel/kgdb.c
arch/powerpc/platforms/cell/spufs/inode.c
arch/s390/Kconfig
arch/s390/hypfs/hypfs_diag.c
arch/s390/hypfs/inode.c
arch/s390/include/asm/dasd.h
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/early.c
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/kprobes.c
arch/s390/kernel/setup.c
arch/s390/kernel/sysinfo.c
arch/s390/kernel/topology.c
arch/s390/kernel/vdso32/clock_getres.S
arch/s390/kernel/vdso32/clock_gettime.S
arch/s390/kernel/vdso64/clock_getres.S
arch/s390/kernel/vdso64/clock_gettime.S
arch/sparc/Kconfig
arch/sparc/include/asm/jump_label.h
arch/sparc/kernel/irq_32.c
arch/sparc/kernel/leon_smp.c
arch/sparc/kernel/rtrap_32.S
arch/sparc/kernel/rtrap_64.S
arch/sparc/mm/fault_32.c
arch/x86/kernel/kgdb.c
drivers/ata/pata_octeon_cf.c
drivers/base/devtmpfs.c
drivers/char/agp/parisc-agp.c
drivers/dma/Kconfig
drivers/ide/hpt366.c
drivers/ide/ide-dma.c
drivers/infiniband/hw/ipath/ipath_fs.c
drivers/infiniband/hw/qib/qib_fs.c
drivers/isdn/capi/capifs.c
drivers/md/bitmap.c
drivers/md/bitmap.h
drivers/md/faulty.c
drivers/md/md.c
drivers/md/md.h
drivers/md/raid1.c
drivers/md/raid1.h
drivers/md/raid10.c
drivers/md/raid5.c
drivers/misc/ibmasm/ibmasmfs.c
drivers/misc/kgdbts.c
drivers/mtd/mtdchar.c
drivers/mtd/mtdsuper.c
drivers/net/Kconfig
drivers/net/atarilance.c
drivers/net/cxgb3/cxgb3_main.c
drivers/net/cxgb3/sge.c
drivers/net/e1000e/82571.c
drivers/net/e1000e/e1000.h
drivers/net/e1000e/netdev.c
drivers/net/igb/igb_main.c
drivers/net/igbvf/netdev.c
drivers/net/ixgb/ixgb_main.c
drivers/net/ixgbe/ixgbe_dcb.c
drivers/net/ixgbe/ixgbe_dcb.h
drivers/net/ixgbe/ixgbe_dcb_82599.c
drivers/net/ixgbe/ixgbe_dcb_82599.h
drivers/net/ixgbe/ixgbe_main.c
drivers/net/lib8390.c
drivers/net/netxen/netxen_nic_ctx.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/stmmac/stmmac_main.c
drivers/net/wireless/ath/ath5k/attach.c
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/hif_usb.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/b43/sdio.c
drivers/net/wireless/libertas/if_sdio.c
drivers/oprofile/oprofilefs.c
drivers/s390/block/dasd_eckd.c
drivers/s390/block/dasd_eckd.h
drivers/s390/char/tape_core.c
drivers/s390/char/tape_std.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/autofs/init.c
drivers/staging/dream/Kconfig [deleted file]
drivers/staging/dream/Makefile [deleted file]
drivers/staging/dream/TODO [deleted file]
drivers/staging/dream/camera/Kconfig [deleted file]
drivers/staging/dream/camera/Makefile [deleted file]
drivers/staging/dream/camera/msm_camera.c [deleted file]
drivers/staging/dream/camera/msm_io7x.c [deleted file]
drivers/staging/dream/camera/msm_io8x.c [deleted file]
drivers/staging/dream/camera/msm_v4l2.c [deleted file]
drivers/staging/dream/camera/msm_vfe7x.c [deleted file]
drivers/staging/dream/camera/msm_vfe7x.h [deleted file]
drivers/staging/dream/camera/msm_vfe8x.c [deleted file]
drivers/staging/dream/camera/msm_vfe8x.h [deleted file]
drivers/staging/dream/camera/msm_vfe8x_proc.c [deleted file]
drivers/staging/dream/camera/msm_vfe8x_proc.h [deleted file]
drivers/staging/dream/camera/mt9d112.c [deleted file]
drivers/staging/dream/camera/mt9d112.h [deleted file]
drivers/staging/dream/camera/mt9d112_reg.c [deleted file]
drivers/staging/dream/camera/mt9p012.h [deleted file]
drivers/staging/dream/camera/mt9p012_fox.c [deleted file]
drivers/staging/dream/camera/mt9p012_reg.c [deleted file]
drivers/staging/dream/camera/mt9t013.c [deleted file]
drivers/staging/dream/camera/mt9t013.h [deleted file]
drivers/staging/dream/camera/mt9t013_reg.c [deleted file]
drivers/staging/dream/camera/s5k3e2fx.c [deleted file]
drivers/staging/dream/camera/s5k3e2fx.h [deleted file]
drivers/staging/dream/generic_gpio.c [deleted file]
drivers/staging/dream/gpio_axis.c [deleted file]
drivers/staging/dream/gpio_event.c [deleted file]
drivers/staging/dream/gpio_input.c [deleted file]
drivers/staging/dream/gpio_matrix.c [deleted file]
drivers/staging/dream/gpio_output.c [deleted file]
drivers/staging/dream/include/linux/android_pmem.h [deleted file]
drivers/staging/dream/include/linux/gpio_event.h [deleted file]
drivers/staging/dream/include/linux/msm_adsp.h [deleted file]
drivers/staging/dream/include/linux/msm_audio.h [deleted file]
drivers/staging/dream/include/linux/msm_rpcrouter.h [deleted file]
drivers/staging/dream/include/linux/wakelock.h [deleted file]
drivers/staging/dream/include/mach/camera.h [deleted file]
drivers/staging/dream/include/mach/msm_adsp.h [deleted file]
drivers/staging/dream/include/mach/msm_rpcrouter.h [deleted file]
drivers/staging/dream/include/mach/msm_smd.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h [deleted file]
drivers/staging/dream/include/media/msm_camera.h [deleted file]
drivers/staging/dream/pmem.c [deleted file]
drivers/staging/dream/qdsp5/Makefile [deleted file]
drivers/staging/dream/qdsp5/adsp.c [deleted file]
drivers/staging/dream/qdsp5/adsp.h [deleted file]
drivers/staging/dream/qdsp5/adsp_6210.c [deleted file]
drivers/staging/dream/qdsp5/adsp_6220.c [deleted file]
drivers/staging/dream/qdsp5/adsp_6225.c [deleted file]
drivers/staging/dream/qdsp5/adsp_driver.c [deleted file]
drivers/staging/dream/qdsp5/adsp_info.c [deleted file]
drivers/staging/dream/qdsp5/adsp_jpeg_patch_event.c [deleted file]
drivers/staging/dream/qdsp5/adsp_jpeg_verify_cmd.c [deleted file]
drivers/staging/dream/qdsp5/adsp_lpm_verify_cmd.c [deleted file]
drivers/staging/dream/qdsp5/adsp_vfe_patch_event.c [deleted file]
drivers/staging/dream/qdsp5/adsp_vfe_verify_cmd.c [deleted file]
drivers/staging/dream/qdsp5/adsp_video_verify_cmd.c [deleted file]
drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c [deleted file]
drivers/staging/dream/qdsp5/audio_aac.c [deleted file]
drivers/staging/dream/qdsp5/audio_amrnb.c [deleted file]
drivers/staging/dream/qdsp5/audio_evrc.c [deleted file]
drivers/staging/dream/qdsp5/audio_in.c [deleted file]
drivers/staging/dream/qdsp5/audio_mp3.c [deleted file]
drivers/staging/dream/qdsp5/audio_out.c [deleted file]
drivers/staging/dream/qdsp5/audio_qcelp.c [deleted file]
drivers/staging/dream/qdsp5/audmgr.c [deleted file]
drivers/staging/dream/qdsp5/audmgr.h [deleted file]
drivers/staging/dream/qdsp5/audmgr_new.h [deleted file]
drivers/staging/dream/qdsp5/audpp.c [deleted file]
drivers/staging/dream/qdsp5/evlog.h [deleted file]
drivers/staging/dream/qdsp5/snd.c [deleted file]
drivers/staging/dream/synaptics_i2c_rmi.c [deleted file]
drivers/staging/dream/synaptics_i2c_rmi.h [deleted file]
drivers/staging/pohmelfs/inode.c
drivers/staging/smbfs/inode.c
drivers/usb/core/inode.c
drivers/usb/gadget/f_fs.c
drivers/usb/gadget/inode.c
drivers/usb/gadget/u_ether.c
drivers/usb/host/Kconfig
drivers/usb/host/Makefile
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-octeon.c [new file with mode: 0644]
drivers/usb/host/octeon2-common.c [new file with mode: 0644]
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-octeon.c [new file with mode: 0644]
drivers/watchdog/octeon-wdt-main.c
drivers/xen/xenfs/super.c
fs/9p/vfs_super.c
fs/adfs/super.c
fs/affs/super.c
fs/afs/super.c
fs/anon_inodes.c
fs/autofs4/init.c
fs/befs/linuxvfs.c
fs/bfs/inode.c
fs/binfmt_misc.c
fs/block_dev.c
fs/btrfs/super.c
fs/ceph/super.c
fs/cifs/Kconfig
fs/cifs/cifsencrypt.c
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/cifspdu.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/misc.c
fs/cifs/sess.c
fs/cifs/transport.c
fs/coda/inode.c
fs/compat.c
fs/configfs/mount.c
fs/cramfs/inode.c
fs/debugfs/inode.c
fs/devpts/inode.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/inode.c
fs/ecryptfs/keystore.c
fs/ecryptfs/main.c
fs/ecryptfs/super.c
fs/efs/super.c
fs/exofs/super.c
fs/ext2/super.c
fs/ext3/super.c
fs/ext4/super.c
fs/fat/namei_msdos.c
fs/fat/namei_vfat.c
fs/freevxfs/vxfs_super.c
fs/fuse/control.c
fs/fuse/inode.c
fs/gfs2/ops_fstype.c
fs/hfs/super.c
fs/hfsplus/super.c
fs/hostfs/hostfs_kern.c
fs/hpfs/super.c
fs/hppfs/hppfs.c
fs/hugetlbfs/inode.c
fs/internal.h
fs/isofs/inode.c
fs/jffs2/super.c
fs/jfs/super.c
fs/libfs.c
fs/logfs/dev_bdev.c
fs/logfs/dev_mtd.c
fs/logfs/logfs.h
fs/logfs/super.c
fs/minix/inode.c
fs/namei.c
fs/ncpfs/inode.c
fs/nfs/super.c
fs/nfs/unlink.c
fs/nfsd/nfsctl.c
fs/nilfs2/super.c
fs/ntfs/super.c
fs/ocfs2/dlmfs/dlmfs.c
fs/ocfs2/super.c
fs/omfs/inode.c
fs/open.c
fs/openpromfs/inode.c
fs/pipe.c
fs/proc/root.c
fs/qnx4/inode.c
fs/ramfs/inode.c
fs/read_write.c
fs/reiserfs/super.c
fs/romfs/super.c
fs/squashfs/super.c
fs/squashfs/xattr.c
fs/squashfs/xattr.h
fs/squashfs/xattr_id.c
fs/super.c
fs/sysfs/mount.c
fs/sysv/super.c
fs/ubifs/super.c
fs/udf/super.c
fs/ufs/super.c
fs/xfs/linux-2.6/xfs_super.c
include/linux/dccp.h
include/linux/fs.h
include/linux/kgdb.h
include/linux/mtd/super.h
include/linux/ramfs.h
include/linux/sched.h
include/linux/socket.h
include/net/ip_fib.h
ipc/mqueue.c
kernel/cgroup.c
kernel/cpuset.c
kernel/debug/debug_core.c
kernel/debug/kdb/kdb_main.c
kernel/sched.c
kernel/sched_fair.c
kernel/sched_stats.h
mm/shmem.c
net/compat.c
net/core/iovec.c
net/core/pktgen.c
net/dccp/ccid.h
net/dccp/ccids/ccid2.c
net/dccp/ccids/ccid2.h
net/dccp/ccids/ccid3.c
net/dccp/dccp.h
net/dccp/output.c
net/dccp/proto.c
net/dccp/timer.c
net/ipv4/fib_frontend.c
net/ipv4/fib_hash.c
net/ipv4/fib_trie.c
net/mac80211/debugfs_key.c
net/mac80211/main.c
net/netfilter/xt_socket.c
net/socket.c
net/sunrpc/rpc_pipe.c
samples/Kconfig
samples/Makefile
samples/kdb/Makefile [new file with mode: 0644]
samples/kdb/kdb_hello.c [new file with mode: 0644]
scripts/kconfig/streamline_config.pl
scripts/recordmcount.c
scripts/recordmcount.h
security/inode.c
security/selinux/selinuxfs.c
security/smack/smackfs.c

index 490d862c5f0ddffc748ebb56de4255ef0769c115..d71b57fcf116bcb263b8a761d2ebf87b3231f56a 100644 (file)
@@ -710,7 +710,18 @@ Task Addr       Pid   Parent [*] cpu State Thread     Command
         <listitem><para>A simple shell</para></listitem>
         <listitem><para>The kdb core command set</para></listitem>
         <listitem><para>A registration API to register additional kdb shell commands.</para>
-        <para>A good example of a self-contained kdb module is the "ftdump" command for dumping the ftrace buffer.  See: kernel/trace/trace_kdb.c</para></listitem>
+       <itemizedlist>
+        <listitem><para>A good example of a self-contained kdb module
+        is the "ftdump" command for dumping the ftrace buffer.  See:
+        kernel/trace/trace_kdb.c</para></listitem>
+        <listitem><para>For an example of how to dynamically register
+        a new kdb command you can build the kdb_hello.ko kernel module
+        from samples/kdb/kdb_hello.c.  To build this example you can
+        set CONFIG_SAMPLES=y and CONFIG_SAMPLE_KDB=m in your kernel
+        config.  Later run "modprobe kdb_hello" and the next time you
+        enter the kdb shell, you can run the "hello"
+        command.</para></listitem>
+       </itemizedlist></listitem>
         <listitem><para>The implementation for kdb_printf() which
         emits messages directly to I/O drivers, bypassing the kernel
         log.</para></listitem>
index 6b23f1b15fc473b0226bf8525b48a8a3a17c8b28..519db43052a047f175501cca984d8058cf382b1c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -204,6 +204,9 @@ ifeq ($(ARCH),x86_64)
 endif
 
 # Additional ARCH settings for sparc
+ifeq ($(ARCH),sparc32)
+       SRCARCH := sparc
+endif
 ifeq ($(ARCH),sparc64)
        SRCARCH := sparc
 endif
index 08265993227fc1d03bec79f7a420f63c005a3f2c..48066ce9ea34f64961111c487fbc4f26e037b842 100644 (file)
@@ -70,7 +70,8 @@ extern int kgdb_fault_expected;
 #define _GP_REGS               16
 #define _FP_REGS               8
 #define _EXTRA_REGS            2
-#define DBG_MAX_REG_NUM                (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS)
+#define GDB_MAX_REGS           (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS)
+#define DBG_MAX_REG_NUM                (_GP_REGS + _FP_REGS + _EXTRA_REGS)
 
 #define KGDB_MAX_NO_CPUS       1
 #define BUFMAX                 400
@@ -93,7 +94,7 @@ extern int kgdb_fault_expected;
 #define _SPT                   13
 #define _LR                    14
 #define _PC                    15
-#define _CPSR                  (DBG_MAX_REG_NUM - 1)
+#define _CPSR                  (GDB_MAX_REGS - 1)
 
 /*
  * So that we can denote the end of a frame for tracing,
index d6e8b4d2e60dacde3ceff47584fe43b75ddb496d..778c2f7024ff57304227ce67665e749f39b05fc7 100644 (file)
@@ -79,7 +79,7 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
                return;
 
        /* Initialize to zero */
-       for (regno = 0; regno < DBG_MAX_REG_NUM; regno++)
+       for (regno = 0; regno < GDB_MAX_REGS; regno++)
                gdb_regs[regno] = 0;
 
        /* Otherwise, we have only some registers from switch_to() */
index 08bc44ea688313976e6d54b6cbb679e395271159..edae461b1c545d4f02e3c91ac664ec55012b9c4c 100644 (file)
@@ -320,7 +320,7 @@ static void bfin_correct_hw_break(void)
        }
 }
 
-void kgdb_disable_hw_debug(struct pt_regs *regs)
+static void bfin_disable_hw_debug(struct pt_regs *regs)
 {
        /* Disable hardware debugging while we are in kgdb */
        bfin_write_WPIACTL(0);
@@ -406,6 +406,7 @@ struct kgdb_arch arch_kgdb_ops = {
 #endif
        .set_hw_breakpoint = bfin_set_hw_break,
        .remove_hw_breakpoint = bfin_remove_hw_break,
+       .disable_hw_break = bfin_disable_hw_debug,
        .remove_all_hw_break = bfin_remove_all_hw_break,
        .correct_hw_break = bfin_correct_hw_break,
 };
index 6b1852f7f972b80fcccc06ba0214acc321cd84e5..39e534f5a3b05fc36c46d1e58b0c581c6c307bc5 100644 (file)
@@ -618,16 +618,15 @@ pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
 }
 
 
-static int
-pfmfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data,
-            struct vfsmount *mnt)
+static struct dentry *
+pfmfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data)
 {
-       return get_sb_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC, mnt);
+       return mount_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC);
 }
 
 static struct file_system_type pfm_fs_type = {
        .name     = "pfmfs",
-       .get_sb   = pfmfs_get_sb,
+       .mount    = pfmfs_mount,
        .kill_sb  = kill_anon_super,
 };
 
index cf8d0945530c4b77f42cde9421c79591efc980f1..67a2fa2caa494ff06e2550aa8cea7cf61d69f39e 100644 (file)
@@ -4,16 +4,21 @@ config MIPS
        select HAVE_GENERIC_DMA_COHERENT
        select HAVE_IDE
        select HAVE_OPROFILE
+       select HAVE_PERF_EVENTS
+       select PERF_USE_VMALLOC
        select HAVE_ARCH_KGDB
        select HAVE_FUNCTION_TRACER
        select HAVE_FUNCTION_TRACE_MCOUNT_TEST
        select HAVE_DYNAMIC_FTRACE
        select HAVE_FTRACE_MCOUNT_RECORD
+       select HAVE_C_RECORDMCOUNT
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_KPROBES
        select HAVE_KRETPROBES
        select RTC_LIB if !MACH_LOONGSON
        select GENERIC_ATOMIC64 if !64BIT
+       select HAVE_DMA_ATTRS
+       select HAVE_DMA_API_DEBUG
 
 menu "Machine selection"
 
@@ -691,6 +696,9 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
        select SWAP_IO_SPACE
        select HW_HAS_PCI
        select ARCH_SUPPORTS_MSI
+       select ZONE_DMA32
+       select USB_ARCH_HAS_OHCI
+       select USB_ARCH_HAS_EHCI
        help
          This option supports all of the Octeon reference boards from Cavium
          Networks. It builds a kernel that dynamically determines the Octeon
@@ -1334,6 +1342,57 @@ config CPU_CAVIUM_OCTEON
          can have up to 16 Mips64v2 cores and 8 integrated gigabit ethernets.
          Full details can be found at http://www.caviumnetworks.com.
 
+config CPU_BMIPS3300
+       bool "BMIPS3300"
+       depends on SYS_HAS_CPU_BMIPS3300
+       select DMA_NONCOHERENT
+       select IRQ_CPU
+       select SWAP_IO_SPACE
+       select SYS_SUPPORTS_32BIT_KERNEL
+       select WEAK_ORDERING
+       help
+         Broadcom BMIPS3300 processors.
+
+config CPU_BMIPS4350
+       bool "BMIPS4350"
+       depends on SYS_HAS_CPU_BMIPS4350
+       select CPU_SUPPORTS_32BIT_KERNEL
+       select DMA_NONCOHERENT
+       select IRQ_CPU
+       select SWAP_IO_SPACE
+       select SYS_SUPPORTS_SMP
+       select SYS_SUPPORTS_HOTPLUG_CPU
+       select WEAK_ORDERING
+       help
+         Broadcom BMIPS4350 ("VIPER") processors.
+
+config CPU_BMIPS4380
+       bool "BMIPS4380"
+       depends on SYS_HAS_CPU_BMIPS4380
+       select CPU_SUPPORTS_32BIT_KERNEL
+       select DMA_NONCOHERENT
+       select IRQ_CPU
+       select SWAP_IO_SPACE
+       select SYS_SUPPORTS_SMP
+       select SYS_SUPPORTS_HOTPLUG_CPU
+       select WEAK_ORDERING
+       help
+         Broadcom BMIPS4380 processors.
+
+config CPU_BMIPS5000
+       bool "BMIPS5000"
+       depends on SYS_HAS_CPU_BMIPS5000
+       select CPU_SUPPORTS_32BIT_KERNEL
+       select CPU_SUPPORTS_HIGHMEM
+       select DMA_NONCOHERENT
+       select IRQ_CPU
+       select SWAP_IO_SPACE
+       select SYS_SUPPORTS_SMP
+       select SYS_SUPPORTS_HOTPLUG_CPU
+       select WEAK_ORDERING
+       help
+         Broadcom BMIPS5000 processors.
+
 endchoice
 
 if CPU_LOONGSON2F
@@ -1452,6 +1511,18 @@ config SYS_HAS_CPU_SB1
 config SYS_HAS_CPU_CAVIUM_OCTEON
        bool
 
+config SYS_HAS_CPU_BMIPS3300
+       bool
+
+config SYS_HAS_CPU_BMIPS4350
+       bool
+
+config SYS_HAS_CPU_BMIPS4380
+       bool
+
+config SYS_HAS_CPU_BMIPS5000
+       bool
+
 #
 # CPU may reorder R->R, R->W, W->R, W->W
 # Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC
@@ -1928,6 +1999,14 @@ config NODES_SHIFT
        default "6"
        depends on NEED_MULTIPLE_NODES
 
+config HW_PERF_EVENTS
+       bool "Enable hardware performance counter support for perf events"
+       depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && CPU_MIPS32
+       default y
+       help
+         Enable hardware performance counter support for perf events. If
+         disabled, perf events will use software events only.
+
 source "mm/Kconfig"
 
 config SMP
index 43dc279977308363e1f0aa538504b5f220cc8cb0..f437cd1fafb8cfc84b7dd97382a7995d09278c67 100644 (file)
@@ -67,6 +67,15 @@ config CMDLINE_OVERRIDE
 
          Normally, you will choose 'N' here.
 
+config DEBUG_STACKOVERFLOW
+       bool "Check for stack overflows"
+       depends on DEBUG_KERNEL
+       help
+         This option will cause messages to be printed if free stack space
+         drops below a certain limit(2GB on MIPS). The debugging option
+         provides another way to check stack overflow happened on kernel mode
+         stack usually caused by nested interruption.
+
 config DEBUG_STACK_USAGE
        bool "Enable stack utilization instrumentation"
        depends on DEBUG_KERNEL
index f4a4b663ebb3150400d5148ba25c108aac289b7d..7c1102e41fe25b917dcce6566c0bf494ceef867e 100644 (file)
@@ -48,9 +48,6 @@ ifneq ($(SUBARCH),$(ARCH))
   endif
 endif
 
-ifndef CONFIG_FUNCTION_TRACER
-cflags-y := -ffunction-sections
-endif
 ifdef CONFIG_FUNCTION_GRAPH_TRACER
   ifndef KBUILD_MCOUNT_RA_ADDRESS
     ifeq ($(call cc-option-yn,-mmcount-ra-address), y)
@@ -159,6 +156,7 @@ cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += $(call cc-option,-march=octeon) -Wa,--trap
 ifeq (,$(findstring march=octeon, $(cflags-$(CONFIG_CPU_CAVIUM_OCTEON))))
 cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon
 endif
+cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1
 
 cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
 cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
index c32fbb57441aceabb3627abc430755133a7164cd..425dfa5d6e12c69380b160edde7edf58477860af 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
  * Copyright (C) 2007 Eugene Konev <ejka@openwrt.org>
- * Copyright (C) 2009 Florian Fainelli <florian@openwrt.org>
+ * Copyright (C) 2009-2010 Florian Fainelli <florian@openwrt.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -37,6 +37,16 @@ static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
        return readl(gpio_in) & (1 << gpio);
 }
 
+static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+       struct ar7_gpio_chip *gpch =
+                               container_of(chip, struct ar7_gpio_chip, chip);
+       void __iomem *gpio_in0 = gpch->regs + TITAN_GPIO_INPUT_0;
+       void __iomem *gpio_in1 = gpch->regs + TITAN_GPIO_INPUT_1;
+
+       return readl(gpio >> 5 ? gpio_in1 : gpio_in0) & (1 << (gpio & 0x1f));
+}
+
 static void ar7_gpio_set_value(struct gpio_chip *chip,
                                unsigned gpio, int value)
 {
@@ -51,6 +61,21 @@ static void ar7_gpio_set_value(struct gpio_chip *chip,
        writel(tmp, gpio_out);
 }
 
+static void titan_gpio_set_value(struct gpio_chip *chip,
+                               unsigned gpio, int value)
+{
+       struct ar7_gpio_chip *gpch =
+                               container_of(chip, struct ar7_gpio_chip, chip);
+       void __iomem *gpio_out0 = gpch->regs + TITAN_GPIO_OUTPUT_0;
+       void __iomem *gpio_out1 = gpch->regs + TITAN_GPIO_OUTPUT_1;
+       unsigned tmp;
+
+       tmp = readl(gpio >> 5 ? gpio_out1 : gpio_out0) & ~(1 << (gpio & 0x1f));
+       if (value)
+               tmp |= 1 << (gpio & 0x1f);
+       writel(tmp, gpio >> 5 ? gpio_out1 : gpio_out0);
+}
+
 static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
 {
        struct ar7_gpio_chip *gpch =
@@ -62,6 +87,21 @@ static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
        return 0;
 }
 
+static int titan_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+       struct ar7_gpio_chip *gpch =
+                               container_of(chip, struct ar7_gpio_chip, chip);
+       void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
+       void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
+
+       if (gpio >= TITAN_GPIO_MAX)
+               return -EINVAL;
+
+       writel(readl(gpio >> 5 ? gpio_dir1 : gpio_dir0) | (1 << (gpio & 0x1f)),
+                       gpio >> 5 ? gpio_dir1 : gpio_dir0);
+       return 0;
+}
+
 static int ar7_gpio_direction_output(struct gpio_chip *chip,
                                        unsigned gpio, int value)
 {
@@ -75,6 +115,24 @@ static int ar7_gpio_direction_output(struct gpio_chip *chip,
        return 0;
 }
 
+static int titan_gpio_direction_output(struct gpio_chip *chip,
+                                       unsigned gpio, int value)
+{
+       struct ar7_gpio_chip *gpch =
+                               container_of(chip, struct ar7_gpio_chip, chip);
+       void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
+       void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
+
+       if (gpio >= TITAN_GPIO_MAX)
+               return -EINVAL;
+
+       titan_gpio_set_value(chip, gpio, value);
+       writel(readl(gpio >> 5 ? gpio_dir1 : gpio_dir0) & ~(1 <<
+               (gpio & 0x1f)), gpio >> 5 ? gpio_dir1 : gpio_dir0);
+
+       return 0;
+}
+
 static struct ar7_gpio_chip ar7_gpio_chip = {
        .chip = {
                .label                  = "ar7-gpio",
@@ -87,7 +145,19 @@ static struct ar7_gpio_chip ar7_gpio_chip = {
        }
 };
 
-int ar7_gpio_enable(unsigned gpio)
+static struct ar7_gpio_chip titan_gpio_chip = {
+       .chip = {
+               .label                  = "titan-gpio",
+               .direction_input        = titan_gpio_direction_input,
+               .direction_output       = titan_gpio_direction_output,
+               .set                    = titan_gpio_set_value,
+               .get                    = titan_gpio_get_value,
+               .base                   = 0,
+               .ngpio                  = TITAN_GPIO_MAX,
+       }
+};
+
+static inline int ar7_gpio_enable_ar7(unsigned gpio)
 {
        void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE;
 
@@ -95,9 +165,26 @@ int ar7_gpio_enable(unsigned gpio)
 
        return 0;
 }
+
+static inline int ar7_gpio_enable_titan(unsigned gpio)
+{
+       void __iomem *gpio_en0 = titan_gpio_chip.regs  + TITAN_GPIO_ENBL_0;
+       void __iomem *gpio_en1 = titan_gpio_chip.regs  + TITAN_GPIO_ENBL_1;
+
+       writel(readl(gpio >> 5 ? gpio_en1 : gpio_en0) | (1 << (gpio & 0x1f)),
+               gpio >> 5 ? gpio_en1 : gpio_en0);
+
+       return 0;
+}
+
+int ar7_gpio_enable(unsigned gpio)
+{
+       return ar7_is_titan() ? ar7_gpio_enable_titan(gpio) :
+                               ar7_gpio_enable_ar7(gpio);
+}
 EXPORT_SYMBOL(ar7_gpio_enable);
 
-int ar7_gpio_disable(unsigned gpio)
+static inline int ar7_gpio_disable_ar7(unsigned gpio)
 {
        void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE;
 
@@ -105,27 +192,159 @@ int ar7_gpio_disable(unsigned gpio)
 
        return 0;
 }
+
+static inline int ar7_gpio_disable_titan(unsigned gpio)
+{
+       void __iomem *gpio_en0 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_0;
+       void __iomem *gpio_en1 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_1;
+
+       writel(readl(gpio >> 5 ? gpio_en1 : gpio_en0) & ~(1 << (gpio & 0x1f)),
+                       gpio >> 5 ? gpio_en1 : gpio_en0);
+
+       return 0;
+}
+
+int ar7_gpio_disable(unsigned gpio)
+{
+       return ar7_is_titan() ? ar7_gpio_disable_titan(gpio) :
+                               ar7_gpio_disable_ar7(gpio);
+}
 EXPORT_SYMBOL(ar7_gpio_disable);
 
-static int __init ar7_gpio_init(void)
+struct titan_gpio_cfg {
+       u32 reg;
+       u32 shift;
+       u32 func;
+};
+
+static struct titan_gpio_cfg titan_gpio_table[] = {
+       /* reg, start bit, mux value */
+       {4, 24, 1},
+       {4, 26, 1},
+       {4, 28, 1},
+       {4, 30, 1},
+       {5, 6, 1},
+       {5, 8, 1},
+       {5, 10, 1},
+       {5, 12, 1},
+       {7, 14, 3},
+       {7, 16, 3},
+       {7, 18, 3},
+       {7, 20, 3},
+       {7, 22, 3},
+       {7, 26, 3},
+       {7, 28, 3},
+       {7, 30, 3},
+       {8, 0, 3},
+       {8, 2, 3},
+       {8, 4, 3},
+       {8, 10, 3},
+       {8, 14, 3},
+       {8, 16, 3},
+       {8, 18, 3},
+       {8, 20, 3},
+       {9, 8, 3},
+       {9, 10, 3},
+       {9, 12, 3},
+       {9, 14, 3},
+       {9, 18, 3},
+       {9, 20, 3},
+       {9, 24, 3},
+       {9, 26, 3},
+       {9, 28, 3},
+       {9, 30, 3},
+       {10, 0, 3},
+       {10, 2, 3},
+       {10, 8, 3},
+       {10, 10, 3},
+       {10, 12, 3},
+       {10, 14, 3},
+       {13, 12, 3},
+       {13, 14, 3},
+       {13, 16, 3},
+       {13, 18, 3},
+       {13, 24, 3},
+       {13, 26, 3},
+       {13, 28, 3},
+       {13, 30, 3},
+       {14, 2, 3},
+       {14, 6, 3},
+       {14, 8, 3},
+       {14, 12, 3}
+};
+
+static int titan_gpio_pinsel(unsigned gpio)
+{
+       struct titan_gpio_cfg gpio_cfg;
+       u32 mux_status, pin_sel_reg, tmp;
+       void __iomem *pin_sel = (void __iomem *)KSEG1ADDR(AR7_REGS_PINSEL);
+
+       if (gpio >= ARRAY_SIZE(titan_gpio_table))
+               return -EINVAL;
+
+       gpio_cfg = titan_gpio_table[gpio];
+       pin_sel_reg = gpio_cfg.reg - 1;
+
+       mux_status = (readl(pin_sel + pin_sel_reg) >> gpio_cfg.shift) & 0x3;
+
+       /* Check the mux status */
+       if (!((mux_status == 0) || (mux_status == gpio_cfg.func)))
+               return 0;
+
+       /* Set the pin sel value */
+       tmp = readl(pin_sel + pin_sel_reg);
+       tmp |= ((gpio_cfg.func & 0x3) << gpio_cfg.shift);
+       writel(tmp, pin_sel + pin_sel_reg);
+
+       return 0;
+}
+
+/* Perform minimal Titan GPIO configuration */
+static void titan_gpio_init(void)
+{
+       unsigned i;
+
+       for (i = 44; i < 48; i++) {
+               titan_gpio_pinsel(i);
+               ar7_gpio_enable_titan(i);
+               titan_gpio_direction_input(&titan_gpio_chip.chip, i);
+       }
+}
+
+int __init ar7_gpio_init(void)
 {
        int ret;
+       struct ar7_gpio_chip *gpch;
+       unsigned size;
+
+       if (!ar7_is_titan()) {
+               gpch = &ar7_gpio_chip;
+               size = 0x10;
+       } else {
+               gpch = &titan_gpio_chip;
+               size = 0x1f;
+       }
 
-       ar7_gpio_chip.regs = ioremap_nocache(AR7_REGS_GPIO,
+       gpch->regs = ioremap_nocache(AR7_REGS_GPIO,
                                        AR7_REGS_GPIO + 0x10);
 
-       if (!ar7_gpio_chip.regs) {
-               printk(KERN_ERR "ar7-gpio: failed to ioremap regs\n");
+       if (!gpch->regs) {
+               printk(KERN_ERR "%s: failed to ioremap regs\n",
+                                       gpch->chip.label);
                return -ENOMEM;
        }
 
-       ret = gpiochip_add(&ar7_gpio_chip.chip);
+       ret = gpiochip_add(&gpch->chip);
        if (ret) {
-               printk(KERN_ERR "ar7-gpio: failed to add gpiochip\n");
+               printk(KERN_ERR "%s: failed to add gpiochip\n",
+                                       gpch->chip.label);
                return ret;
        }
-       printk(KERN_INFO "ar7-gpio: registered %d GPIOs\n",
-                               ar7_gpio_chip.chip.ngpio);
+       printk(KERN_INFO "%s: registered %d GPIOs\n",
+                               gpch->chip.label, gpch->chip.ngpio);
+
+       if (ar7_is_titan())
+               titan_gpio_init();
+
        return ret;
 }
-arch_initcall(ar7_gpio_init);
index 0da5b2b8dd88a4a08d75b4eaf9aa3965b1af655f..7d2fab392327003311ac282483e99f0a398d2e4f 100644 (file)
@@ -357,6 +357,11 @@ static struct gpio_led default_leds[] = {
        },
 };
 
+static struct gpio_led titan_leds[] = {
+       { .name = "status", .gpio = 8, .active_low = 1, },
+       { .name = "wifi", .gpio = 13, .active_low = 1, },
+};
+
 static struct gpio_led dsl502t_leds[] = {
        {
                .name                   = "status",
@@ -495,6 +500,9 @@ static void __init detect_leds(void)
        } else if (strstr(prid, "DG834")) {
                ar7_led_data.num_leds = ARRAY_SIZE(dg834g_leds);
                ar7_led_data.leds = dg834g_leds;
+       } else if (strstr(prid, "CYWM") || strstr(prid, "CYWL")) {
+               ar7_led_data.num_leds = ARRAY_SIZE(titan_leds);
+               ar7_led_data.leds = titan_leds;
        }
 }
 
@@ -560,6 +568,51 @@ static int __init ar7_register_uarts(void)
        return 0;
 }
 
+static void __init titan_fixup_devices(void)
+{
+       /* Set vlynq0 data */
+       vlynq_low_data.reset_bit = 15;
+       vlynq_low_data.gpio_bit = 14;
+
+       /* Set vlynq1 data */
+       vlynq_high_data.reset_bit = 16;
+       vlynq_high_data.gpio_bit = 7;
+
+       /* Set vlynq0 resources */
+       vlynq_low_res[0].start = TITAN_REGS_VLYNQ0;
+       vlynq_low_res[0].end = TITAN_REGS_VLYNQ0 + 0xff;
+       vlynq_low_res[1].start = 33;
+       vlynq_low_res[1].end = 33;
+       vlynq_low_res[2].start = 0x0c000000;
+       vlynq_low_res[2].end = 0x0fffffff;
+       vlynq_low_res[3].start = 80;
+       vlynq_low_res[3].end = 111;
+
+       /* Set vlynq1 resources */
+       vlynq_high_res[0].start = TITAN_REGS_VLYNQ1;
+       vlynq_high_res[0].end = TITAN_REGS_VLYNQ1 + 0xff;
+       vlynq_high_res[1].start = 34;
+       vlynq_high_res[1].end = 34;
+       vlynq_high_res[2].start = 0x40000000;
+       vlynq_high_res[2].end = 0x43ffffff;
+       vlynq_high_res[3].start = 112;
+       vlynq_high_res[3].end = 143;
+
+       /* Set cpmac0 data */
+       cpmac_low_data.phy_mask = 0x40000000;
+
+       /* Set cpmac1 data */
+       cpmac_high_data.phy_mask = 0x80000000;
+
+       /* Set cpmac0 resources */
+       cpmac_low_res[0].start = TITAN_REGS_MAC0;
+       cpmac_low_res[0].end = TITAN_REGS_MAC0 + 0x7ff;
+
+       /* Set cpmac1 resources */
+       cpmac_high_res[0].start = TITAN_REGS_MAC1;
+       cpmac_high_res[0].end = TITAN_REGS_MAC1 + 0x7ff;
+}
+
 static int __init ar7_register_devices(void)
 {
        void __iomem *bootcr;
@@ -574,6 +627,9 @@ static int __init ar7_register_devices(void)
        if (res)
                pr_warning("unable to register physmap-flash: %d\n", res);
 
+       if (ar7_is_titan())
+               titan_fixup_devices();
+
        ar7_device_disable(vlynq_low_data.reset_bit);
        res = platform_device_register(&vlynq_low);
        if (res)
index 52385790e5c168c70eacec3dc74feab7d755b459..23818d299127ce96434ba6c21c378ac8b35739af 100644 (file)
@@ -246,6 +246,8 @@ void __init prom_init(void)
        ar7_init_cmdline(fw_arg0, (char **)fw_arg1);
        ar7_init_env((struct env_var *)fw_arg2);
        console_config();
+
+       ar7_gpio_init();
 }
 
 #define PORT(offset) (KSEG1ADDR(AR7_REGS_UART0 + (offset * 4)))
index 3a801d2cb6e5531ce64622c36a58e28b1263faea..f20b53e597c42fca192bc40866da920452c36cb9 100644 (file)
@@ -23,6 +23,7 @@
 #include <asm/reboot.h>
 #include <asm/mach-ar7/ar7.h>
 #include <asm/mach-ar7/prom.h>
+#include <asm/mach-ar7/gpio.h>
 
 static void ar7_machine_restart(char *command)
 {
@@ -49,6 +50,8 @@ static void ar7_machine_power_off(void)
 const char *get_system_type(void)
 {
        u16 chip_id = ar7_chip_id();
+       u16 titan_variant_id = titan_chip_id();
+
        switch (chip_id) {
        case AR7_CHIP_7100:
                return "TI AR7 (TNETD7100)";
@@ -56,6 +59,17 @@ const char *get_system_type(void)
                return "TI AR7 (TNETD7200)";
        case AR7_CHIP_7300:
                return "TI AR7 (TNETD7300)";
+       case AR7_CHIP_TITAN:
+               switch (titan_variant_id) {
+               case TITAN_CHIP_1050:
+                       return "TI AR7 (TNETV1050)";
+               case TITAN_CHIP_1055:
+                       return "TI AR7 (TNETV1055)";
+               case TITAN_CHIP_1056:
+                       return "TI AR7 (TNETV1056)";
+               case TITAN_CHIP_1060:
+                       return "TI AR7 (TNETV1060)";
+               }
        default:
                return "TI AR7 (unknown)";
        }
index cbb7caf86d77bce79656ed1aff48521552853b02..7c7e4d4486ce0d0099ab2cd92bca6d426237d2b8 100644 (file)
@@ -10,7 +10,9 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/cpu.h>
+#include <asm/cpu.h>
 #include <asm/cpu-info.h>
+#include <asm/mipsregs.h>
 #include <bcm63xx_cpu.h>
 #include <bcm63xx_regs.h>
 #include <bcm63xx_io.h>
@@ -296,26 +298,24 @@ void __init bcm63xx_cpu_init(void)
        expected_cpu_id = 0;
 
        switch (c->cputype) {
-       /*
-        * BCM6338 as the same PrId as BCM3302 see arch/mips/kernel/cpu-probe.c
-        */
-       case CPU_BCM3302:
-               __cpu_name[cpu] = "Broadcom BCM6338";
-               expected_cpu_id = BCM6338_CPU_ID;
-               bcm63xx_regs_base = bcm96338_regs_base;
-               bcm63xx_irqs = bcm96338_irqs;
+       case CPU_BMIPS3300:
+               if ((read_c0_prid() & 0xff00) == PRID_IMP_BMIPS3300_ALT) {
+                       expected_cpu_id = BCM6348_CPU_ID;
+                       bcm63xx_regs_base = bcm96348_regs_base;
+                       bcm63xx_irqs = bcm96348_irqs;
+               } else {
+                       __cpu_name[cpu] = "Broadcom BCM6338";
+                       expected_cpu_id = BCM6338_CPU_ID;
+                       bcm63xx_regs_base = bcm96338_regs_base;
+                       bcm63xx_irqs = bcm96338_irqs;
+               }
                break;
-       case CPU_BCM6345:
+       case CPU_BMIPS32:
                expected_cpu_id = BCM6345_CPU_ID;
                bcm63xx_regs_base = bcm96345_regs_base;
                bcm63xx_irqs = bcm96345_irqs;
                break;
-       case CPU_BCM6348:
-               expected_cpu_id = BCM6348_CPU_ID;
-               bcm63xx_regs_base = bcm96348_regs_base;
-               bcm63xx_irqs = bcm96348_irqs;
-               break;
-       case CPU_BCM6358:
+       case CPU_BMIPS4350:
                expected_cpu_id = BCM6358_CPU_ID;
                bcm63xx_regs_base = bcm96358_regs_base;
                bcm63xx_irqs = bcm96358_irqs;
index 47323ca452dcbde751536c58c9f613dd1d9d51c8..caae22858163a193b681e0adb920590d3d0bcd20 100644 (file)
@@ -3,6 +3,17 @@ config CAVIUM_OCTEON_SPECIFIC_OPTIONS
        depends on CPU_CAVIUM_OCTEON
        default "y"
 
+config CAVIUM_CN63XXP1
+       bool "Enable CN63XXP1 errata worarounds"
+       depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS
+       default "n"
+       help
+         The CN63XXP1 chip requires build time workarounds to
+         function reliably, select this option to enable them.  These
+         workarounds will cause a slight decrease in performance on
+         non-CN63XXP1 hardware, so it is recommended to select "n"
+         unless it is known the workarounds are needed.
+
 config CAVIUM_OCTEON_2ND_KERNEL
        bool "Build the kernel to be used as a 2nd kernel on the same chip"
        depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS
@@ -87,3 +98,15 @@ config ARCH_SPARSEMEM_ENABLE
 config CAVIUM_OCTEON_HELPER
        def_bool y
        depends on OCTEON_ETHERNET || PCI
+
+config IOMMU_HELPER
+       bool
+
+config NEED_SG_DMA_LENGTH
+       bool
+
+config SWIOTLB
+       def_bool y
+       depends on CPU_CAVIUM_OCTEON
+       select IOMMU_HELPER
+       select NEED_SG_DMA_LENGTH
index b6847c8e0ddd3784b4050b7dee6558cfd595e119..26bf71130bf8b1dd6fe1d24c8b5e336a2b30b78d 100644 (file)
@@ -4,14 +4,18 @@
  * for more details.
  *
  * Copyright (C) 2007 by Ralf Baechle
+ * Copyright (C) 2009, 2010 Cavium Networks, Inc.
  */
 #include <linux/clocksource.h>
 #include <linux/init.h>
+#include <linux/smp.h>
 
+#include <asm/cpu-info.h>
 #include <asm/time.h>
 
 #include <asm/octeon/octeon.h>
 #include <asm/octeon/cvmx-ipd-defs.h>
+#include <asm/octeon/cvmx-mio-defs.h>
 
 /*
  * Set the current core's cvmcount counter to the value of the
  * on-line.  This allows for a read from a local cpu register to
  * access a synchronized counter.
  *
+ * On CPU_CAVIUM_OCTEON2 the IPD_CLK_COUNT is scaled by rdiv/sdiv.
  */
 void octeon_init_cvmcount(void)
 {
        unsigned long flags;
        unsigned loops = 2;
+       u64 f = 0;
+       u64 rdiv = 0;
+       u64 sdiv = 0;
+       if (current_cpu_type() == CPU_CAVIUM_OCTEON2) {
+               union cvmx_mio_rst_boot rst_boot;
+               rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
+               rdiv = rst_boot.s.c_mul;        /* CPU clock */
+               sdiv = rst_boot.s.pnr_mul;      /* I/O clock */
+               f = (0x8000000000000000ull / sdiv) * 2;
+       }
+
 
        /* Clobber loops so GCC will not unroll the following while loop. */
        asm("" : "+r" (loops));
@@ -33,8 +49,20 @@ void octeon_init_cvmcount(void)
         * Loop several times so we are executing from the cache,
         * which should give more deterministic timing.
         */
-       while (loops--)
-               write_c0_cvmcount(cvmx_read_csr(CVMX_IPD_CLK_COUNT));
+       while (loops--) {
+               u64 ipd_clk_count = cvmx_read_csr(CVMX_IPD_CLK_COUNT);
+               if (rdiv != 0) {
+                       ipd_clk_count *= rdiv;
+                       if (f != 0) {
+                               asm("dmultu\t%[cnt],%[f]\n\t"
+                                   "mfhi\t%[cnt]"
+                                   : [cnt] "+r" (ipd_clk_count),
+                                     [f] "=r" (f)
+                                   : : "hi", "lo");
+                       }
+               }
+               write_c0_cvmcount(ipd_clk_count);
+       }
        local_irq_restore(flags);
 }
 
@@ -77,7 +105,7 @@ unsigned long long notrace sched_clock(void)
 void __init plat_time_init(void)
 {
        clocksource_mips.rating = 300;
-       clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
+       clocksource_set_clock(&clocksource_mips, octeon_get_clock_rate());
        clocksource_register(&clocksource_mips);
 }
 
index d22b5a2d64f47988659f55d2998925ff569b0711..1abb66caaa1d84459e5564fe788b0d39e61f4aeb 100644 (file)
  * Copyright (C) 2005 Ilya A. Volynets-Evenbakh <ilya@total-knowledge.com>
  * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
  * IP32 changes by Ilya.
- * Cavium Networks: Create new dma setup for Cavium Networks Octeon based on
- * the kernels original.
+ * Copyright (C) 2010 Cavium Networks, Inc.
  */
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/string.h>
 #include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
 #include <linux/scatterlist.h>
+#include <linux/bootmem.h>
+#include <linux/swiotlb.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
 
-#include <linux/cache.h>
-#include <linux/io.h>
+#include <asm/bootinfo.h>
 
 #include <asm/octeon/octeon.h>
+
+#ifdef CONFIG_PCI
+#include <asm/octeon/pci-octeon.h>
 #include <asm/octeon/cvmx-npi-defs.h>
 #include <asm/octeon/cvmx-pci-defs.h>
 
-#include <dma-coherence.h>
+static dma_addr_t octeon_hole_phys_to_dma(phys_addr_t paddr)
+{
+       if (paddr >= CVMX_PCIE_BAR1_PHYS_BASE && paddr < (CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_PHYS_SIZE))
+               return paddr - CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_RC_BASE;
+       else
+               return paddr;
+}
 
-#ifdef CONFIG_PCI
-#include <asm/octeon/pci-octeon.h>
-#endif
+static phys_addr_t octeon_hole_dma_to_phys(dma_addr_t daddr)
+{
+       if (daddr >= CVMX_PCIE_BAR1_RC_BASE)
+               return daddr + CVMX_PCIE_BAR1_PHYS_BASE - CVMX_PCIE_BAR1_RC_BASE;
+       else
+               return daddr;
+}
+
+static dma_addr_t octeon_gen1_phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+       if (paddr >= 0x410000000ull && paddr < 0x420000000ull)
+               paddr -= 0x400000000ull;
+       return octeon_hole_phys_to_dma(paddr);
+}
 
-#define BAR2_PCI_ADDRESS 0x8000000000ul
+static phys_addr_t octeon_gen1_dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+       daddr = octeon_hole_dma_to_phys(daddr);
 
-struct bar1_index_state {
-       int16_t ref_count;      /* Number of PCI mappings using this index */
-       uint16_t address_bits;  /* Upper bits of physical address. This is
-                                  shifted 22 bits */
-};
+       if (daddr >= 0x10000000ull && daddr < 0x20000000ull)
+               daddr += 0x400000000ull;
 
-#ifdef CONFIG_PCI
-static DEFINE_RAW_SPINLOCK(bar1_lock);
-static struct bar1_index_state bar1_state[32];
-#endif
+       return daddr;
+}
 
-dma_addr_t octeon_map_dma_mem(struct device *dev, void *ptr, size_t size)
+static dma_addr_t octeon_big_phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
-#ifndef CONFIG_PCI
-       /* Without PCI/PCIe this function can be called for Octeon internal
-          devices such as USB. These devices all support 64bit addressing */
+       if (paddr >= 0x410000000ull && paddr < 0x420000000ull)
+               paddr -= 0x400000000ull;
+
+       /* Anything in the BAR1 hole or above goes via BAR2 */
+       if (paddr >= 0xf0000000ull)
+               paddr = OCTEON_BAR2_PCI_ADDRESS + paddr;
+
+       return paddr;
+}
+
+static phys_addr_t octeon_big_dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+       if (daddr >= OCTEON_BAR2_PCI_ADDRESS)
+               daddr -= OCTEON_BAR2_PCI_ADDRESS;
+
+       if (daddr >= 0x10000000ull && daddr < 0x20000000ull)
+               daddr += 0x400000000ull;
+       return daddr;
+}
+
+static dma_addr_t octeon_small_phys_to_dma(struct device *dev,
+                                          phys_addr_t paddr)
+{
+       if (paddr >= 0x410000000ull && paddr < 0x420000000ull)
+               paddr -= 0x400000000ull;
+
+       /* Anything not in the BAR1 range goes via BAR2 */
+       if (paddr >= octeon_bar1_pci_phys && paddr < octeon_bar1_pci_phys + 0x8000000ull)
+               paddr = paddr - octeon_bar1_pci_phys;
+       else
+               paddr = OCTEON_BAR2_PCI_ADDRESS + paddr;
+
+       return paddr;
+}
+
+static phys_addr_t octeon_small_dma_to_phys(struct device *dev,
+                                           dma_addr_t daddr)
+{
+       if (daddr >= OCTEON_BAR2_PCI_ADDRESS)
+               daddr -= OCTEON_BAR2_PCI_ADDRESS;
+       else
+               daddr += octeon_bar1_pci_phys;
+
+       if (daddr >= 0x10000000ull && daddr < 0x20000000ull)
+               daddr += 0x400000000ull;
+       return daddr;
+}
+
+#endif /* CONFIG_PCI */
+
+static dma_addr_t octeon_dma_map_page(struct device *dev, struct page *page,
+       unsigned long offset, size_t size, enum dma_data_direction direction,
+       struct dma_attrs *attrs)
+{
+       dma_addr_t daddr = swiotlb_map_page(dev, page, offset, size,
+                                           direction, attrs);
        mb();
-       return virt_to_phys(ptr);
-#else
-       unsigned long flags;
-       uint64_t dma_mask;
-       int64_t start_index;
-       dma_addr_t result = -1;
-       uint64_t physical = virt_to_phys(ptr);
-       int64_t index;
 
+       return daddr;
+}
+
+static int octeon_dma_map_sg(struct device *dev, struct scatterlist *sg,
+       int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
+{
+       int r = swiotlb_map_sg_attrs(dev, sg, nents, direction, attrs);
        mb();
-       /*
-        * Use the DMA masks to determine the allowed memory
-        * region. For us it doesn't limit the actual memory, just the
-        * address visible over PCI.  Devices with limits need to use
-        * lower indexed Bar1 entries.
-        */
-       if (dev) {
-               dma_mask = dev->coherent_dma_mask;
-               if (dev->dma_mask)
-                       dma_mask = *dev->dma_mask;
-       } else {
-               dma_mask = 0xfffffffful;
-       }
+       return r;
+}
 
-       /*
-        * Platform devices, such as the internal USB, skip all
-        * translation and use Octeon physical addresses directly.
-        */
-       if (!dev || dev->bus == &platform_bus_type)
-               return physical;
+static void octeon_dma_sync_single_for_device(struct device *dev,
+       dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
+{
+       swiotlb_sync_single_for_device(dev, dma_handle, size, direction);
+       mb();
+}
 
-       switch (octeon_dma_bar_type) {
-       case OCTEON_DMA_BAR_TYPE_PCIE:
-               if (unlikely(physical < (16ul << 10)))
-                       panic("dma_map_single: Not allowed to map first 16KB."
-                             " It interferes with BAR0 special area\n");
-               else if ((physical + size >= (256ul << 20)) &&
-                        (physical < (512ul << 20)))
-                       panic("dma_map_single: Not allowed to map bootbus\n");
-               else if ((physical + size >= 0x400000000ull) &&
-                        physical < 0x410000000ull)
-                       panic("dma_map_single: "
-                             "Attempt to map illegal memory address 0x%llx\n",
-                             physical);
-               else if (physical >= 0x420000000ull)
-                       panic("dma_map_single: "
-                             "Attempt to map illegal memory address 0x%llx\n",
-                             physical);
-               else if (physical >= CVMX_PCIE_BAR1_PHYS_BASE &&
-                        physical + size < (CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_PHYS_SIZE)) {
-                       result = physical - CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_RC_BASE;
-
-                       if (((result+size-1) & dma_mask) != result+size-1)
-                               panic("dma_map_single: Attempt to map address 0x%llx-0x%llx, which can't be accessed according to the dma mask 0x%llx\n",
-                                     physical, physical+size-1, dma_mask);
-                       goto done;
-               }
-
-               /* The 2nd 256MB is mapped at 256<<20 instead of 0x410000000 */
-               if ((physical >= 0x410000000ull) && physical < 0x420000000ull)
-                       result = physical - 0x400000000ull;
-               else
-                       result = physical;
-               if (((result+size-1) & dma_mask) != result+size-1)
-                       panic("dma_map_single: Attempt to map address "
-                             "0x%llx-0x%llx, which can't be accessed "
-                             "according to the dma mask 0x%llx\n",
-                             physical, physical+size-1, dma_mask);
-               goto done;
+static void octeon_dma_sync_sg_for_device(struct device *dev,
+       struct scatterlist *sg, int nelems, enum dma_data_direction direction)
+{
+       swiotlb_sync_sg_for_device(dev, sg, nelems, direction);
+       mb();
+}
 
-       case OCTEON_DMA_BAR_TYPE_BIG:
-#ifdef CONFIG_64BIT
-               /* If the device supports 64bit addressing, then use BAR2 */
-               if (dma_mask > BAR2_PCI_ADDRESS) {
-                       result = physical + BAR2_PCI_ADDRESS;
-                       goto done;
-               }
-#endif
-               if (unlikely(physical < (4ul << 10))) {
-                       panic("dma_map_single: Not allowed to map first 4KB. "
-                             "It interferes with BAR0 special area\n");
-               } else if (physical < (256ul << 20)) {
-                       if (unlikely(physical + size > (256ul << 20)))
-                               panic("dma_map_single: Requested memory spans "
-                                     "Bar0 0:256MB and bootbus\n");
-                       result = physical;
-                       goto done;
-               } else if (unlikely(physical < (512ul << 20))) {
-                       panic("dma_map_single: Not allowed to map bootbus\n");
-               } else if (physical < (2ul << 30)) {
-                       if (unlikely(physical + size > (2ul << 30)))
-                               panic("dma_map_single: Requested memory spans "
-                                     "Bar0 512MB:2GB and BAR1\n");
-                       result = physical;
-                       goto done;
-               } else if (physical < (2ul << 30) + (128 << 20)) {
-                       /* Fall through */
-               } else if (physical <
-                          (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20)) {
-                       if (unlikely
-                           (physical + size >
-                            (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20)))
-                               panic("dma_map_single: Requested memory "
-                                     "extends past Bar1 (4GB-%luMB)\n",
-                                     OCTEON_PCI_BAR1_HOLE_SIZE);
-                       result = physical;
-                       goto done;
-               } else if ((physical >= 0x410000000ull) &&
-                          (physical < 0x420000000ull)) {
-                       if (unlikely(physical + size > 0x420000000ull))
-                               panic("dma_map_single: Requested memory spans "
-                                     "non existant memory\n");
-                       /* BAR0 fixed mapping 256MB:512MB ->
-                        * 16GB+256MB:16GB+512MB */
-                       result = physical - 0x400000000ull;
-                       goto done;
-               } else {
-                       /* Continued below switch statement */
-               }
-               break;
+static void *octeon_dma_alloc_coherent(struct device *dev, size_t size,
+       dma_addr_t *dma_handle, gfp_t gfp)
+{
+       void *ret;
 
-       case OCTEON_DMA_BAR_TYPE_SMALL:
-#ifdef CONFIG_64BIT
-               /* If the device supports 64bit addressing, then use BAR2 */
-               if (dma_mask > BAR2_PCI_ADDRESS) {
-                       result = physical + BAR2_PCI_ADDRESS;
-                       goto done;
-               }
+       if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
+               return ret;
+
+       /* ignore region specifiers */
+       gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
+
+#ifdef CONFIG_ZONE_DMA
+       if (dev == NULL)
+               gfp |= __GFP_DMA;
+       else if (dev->coherent_dma_mask <= DMA_BIT_MASK(24))
+               gfp |= __GFP_DMA;
+       else
 #endif
-               /* Continued below switch statement */
-               break;
+#ifdef CONFIG_ZONE_DMA32
+            if (dev->coherent_dma_mask <= DMA_BIT_MASK(32))
+               gfp |= __GFP_DMA32;
+       else
+#endif
+               ;
 
-       default:
-               panic("dma_map_single: Invalid octeon_dma_bar_type\n");
-       }
+       /* Don't invoke OOM killer */
+       gfp |= __GFP_NORETRY;
 
-       /* Don't allow mapping to span multiple Bar entries. The hardware guys
-          won't guarantee that DMA across boards work */
-       if (unlikely((physical >> 22) != ((physical + size - 1) >> 22)))
-               panic("dma_map_single: "
-                     "Requested memory spans more than one Bar1 entry\n");
+       ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
 
-       if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG)
-               start_index = 31;
-       else if (unlikely(dma_mask < (1ul << 27)))
-               start_index = (dma_mask >> 22);
-       else
-               start_index = 31;
-
-       /* Only one processor can access the Bar register at once */
-       raw_spin_lock_irqsave(&bar1_lock, flags);
-
-       /* Look through Bar1 for existing mapping that will work */
-       for (index = start_index; index >= 0; index--) {
-               if ((bar1_state[index].address_bits == physical >> 22) &&
-                   (bar1_state[index].ref_count)) {
-                       /* An existing mapping will work, use it */
-                       bar1_state[index].ref_count++;
-                       if (unlikely(bar1_state[index].ref_count < 0))
-                               panic("dma_map_single: "
-                                     "Bar1[%d] reference count overflowed\n",
-                                     (int) index);
-                       result = (index << 22) | (physical & ((1 << 22) - 1));
-                       /* Large BAR1 is offset at 2GB */
-                       if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG)
-                               result += 2ul << 30;
-                       goto done_unlock;
-               }
-       }
+       mb();
 
-       /* No existing mappings, look for a free entry */
-       for (index = start_index; index >= 0; index--) {
-               if (unlikely(bar1_state[index].ref_count == 0)) {
-                       union cvmx_pci_bar1_indexx bar1_index;
-                       /* We have a free entry, use it */
-                       bar1_state[index].ref_count = 1;
-                       bar1_state[index].address_bits = physical >> 22;
-                       bar1_index.u32 = 0;
-                       /* Address bits[35:22] sent to L2C */
-                       bar1_index.s.addr_idx = physical >> 22;
-                       /* Don't put PCI accesses in L2. */
-                       bar1_index.s.ca = 1;
-                       /* Endian Swap Mode */
-                       bar1_index.s.end_swp = 1;
-                       /* Set '1' when the selected address range is valid. */
-                       bar1_index.s.addr_v = 1;
-                       octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index),
-                                          bar1_index.u32);
-                       /* An existing mapping will work, use it */
-                       result = (index << 22) | (physical & ((1 << 22) - 1));
-                       /* Large BAR1 is offset at 2GB */
-                       if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG)
-                               result += 2ul << 30;
-                       goto done_unlock;
-               }
-       }
+       return ret;
+}
 
-       pr_err("dma_map_single: "
-              "Can't find empty BAR1 index for physical mapping 0x%llx\n",
-              (unsigned long long) physical);
+static void octeon_dma_free_coherent(struct device *dev, size_t size,
+       void *vaddr, dma_addr_t dma_handle)
+{
+       int order = get_order(size);
 
-done_unlock:
-       raw_spin_unlock_irqrestore(&bar1_lock, flags);
-done:
-       pr_debug("dma_map_single 0x%llx->0x%llx\n", physical, result);
-       return result;
-#endif
+       if (dma_release_from_coherent(dev, order, vaddr))
+               return;
+
+       swiotlb_free_coherent(dev, size, vaddr, dma_handle);
 }
 
-void octeon_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
+static dma_addr_t octeon_unity_phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
-#ifndef CONFIG_PCI
-       /*
-        * Without PCI/PCIe this function can be called for Octeon internal
-        * devices such as USB. These devices all support 64bit addressing.
-        */
-       return;
-#else
-       unsigned long flags;
-       uint64_t index;
+       return paddr;
+}
 
+static phys_addr_t octeon_unity_dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+       return daddr;
+}
+
+struct octeon_dma_map_ops {
+       struct dma_map_ops dma_map_ops;
+       dma_addr_t (*phys_to_dma)(struct device *dev, phys_addr_t paddr);
+       phys_addr_t (*dma_to_phys)(struct device *dev, dma_addr_t daddr);
+};
+
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+       struct octeon_dma_map_ops *ops = container_of(get_dma_ops(dev),
+                                                     struct octeon_dma_map_ops,
+                                                     dma_map_ops);
+
+       return ops->phys_to_dma(dev, paddr);
+}
+EXPORT_SYMBOL(phys_to_dma);
+
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+       struct octeon_dma_map_ops *ops = container_of(get_dma_ops(dev),
+                                                     struct octeon_dma_map_ops,
+                                                     dma_map_ops);
+
+       return ops->dma_to_phys(dev, daddr);
+}
+EXPORT_SYMBOL(dma_to_phys);
+
+static struct octeon_dma_map_ops octeon_linear_dma_map_ops = {
+       .dma_map_ops = {
+               .alloc_coherent = octeon_dma_alloc_coherent,
+               .free_coherent = octeon_dma_free_coherent,
+               .map_page = octeon_dma_map_page,
+               .unmap_page = swiotlb_unmap_page,
+               .map_sg = octeon_dma_map_sg,
+               .unmap_sg = swiotlb_unmap_sg_attrs,
+               .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
+               .sync_single_for_device = octeon_dma_sync_single_for_device,
+               .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+               .sync_sg_for_device = octeon_dma_sync_sg_for_device,
+               .mapping_error = swiotlb_dma_mapping_error,
+               .dma_supported = swiotlb_dma_supported
+       },
+       .phys_to_dma = octeon_unity_phys_to_dma,
+       .dma_to_phys = octeon_unity_dma_to_phys
+};
+
+char *octeon_swiotlb;
+
+void __init plat_swiotlb_setup(void)
+{
+       int i;
+       phys_t max_addr;
+       phys_t addr_size;
+       size_t swiotlbsize;
+       unsigned long swiotlb_nslabs;
+
+       max_addr = 0;
+       addr_size = 0;
+
+       for (i = 0 ; i < boot_mem_map.nr_map; i++) {
+               struct boot_mem_map_entry *e = &boot_mem_map.map[i];
+               if (e->type != BOOT_MEM_RAM)
+                       continue;
+
+               /* These addresses map low for PCI. */
+               if (e->addr > 0x410000000ull)
+                       continue;
+
+               addr_size += e->size;
+
+               if (max_addr < e->addr + e->size)
+                       max_addr = e->addr + e->size;
+
+       }
+
+       swiotlbsize = PAGE_SIZE;
+
+#ifdef CONFIG_PCI
        /*
-        * Platform devices, such as the internal USB, skip all
-        * translation and use Octeon physical addresses directly.
+        * For OCTEON_DMA_BAR_TYPE_SMALL, size the iotlb at 1/4 memory
+        * size to a maximum of 64MB
         */
-       if (dev->bus == &platform_bus_type)
-               return;
+       if (OCTEON_IS_MODEL(OCTEON_CN31XX)
+           || OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2)) {
+               swiotlbsize = addr_size / 4;
+               if (swiotlbsize > 64 * (1<<20))
+                       swiotlbsize = 64 * (1<<20);
+       } else if (max_addr > 0xf0000000ul) {
+               /*
+                * Otherwise only allocate a big iotlb if there is
+                * memory past the BAR1 hole.
+                */
+               swiotlbsize = 64 * (1<<20);
+       }
+#endif
+       swiotlb_nslabs = swiotlbsize >> IO_TLB_SHIFT;
+       swiotlb_nslabs = ALIGN(swiotlb_nslabs, IO_TLB_SEGSIZE);
+       swiotlbsize = swiotlb_nslabs << IO_TLB_SHIFT;
+
+       octeon_swiotlb = alloc_bootmem_low_pages(swiotlbsize);
 
+       swiotlb_init_with_tbl(octeon_swiotlb, swiotlb_nslabs, 1);
+
+       mips_dma_map_ops = &octeon_linear_dma_map_ops.dma_map_ops;
+}
+
+#ifdef CONFIG_PCI
+static struct octeon_dma_map_ops _octeon_pci_dma_map_ops = {
+       .dma_map_ops = {
+               .alloc_coherent = octeon_dma_alloc_coherent,
+               .free_coherent = octeon_dma_free_coherent,
+               .map_page = octeon_dma_map_page,
+               .unmap_page = swiotlb_unmap_page,
+               .map_sg = octeon_dma_map_sg,
+               .unmap_sg = swiotlb_unmap_sg_attrs,
+               .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
+               .sync_single_for_device = octeon_dma_sync_single_for_device,
+               .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+               .sync_sg_for_device = octeon_dma_sync_sg_for_device,
+               .mapping_error = swiotlb_dma_mapping_error,
+               .dma_supported = swiotlb_dma_supported
+       },
+};
+
+struct dma_map_ops *octeon_pci_dma_map_ops;
+
+void __init octeon_pci_dma_init(void)
+{
        switch (octeon_dma_bar_type) {
        case OCTEON_DMA_BAR_TYPE_PCIE:
-               /* Nothing to do, all mappings are static */
-               goto done;
-
+               _octeon_pci_dma_map_ops.phys_to_dma = octeon_gen1_phys_to_dma;
+               _octeon_pci_dma_map_ops.dma_to_phys = octeon_gen1_dma_to_phys;
+               break;
        case OCTEON_DMA_BAR_TYPE_BIG:
-#ifdef CONFIG_64BIT
-               /* Nothing to do for addresses using BAR2 */
-               if (dma_addr >= BAR2_PCI_ADDRESS)
-                       goto done;
-#endif
-               if (unlikely(dma_addr < (4ul << 10)))
-                       panic("dma_unmap_single: Unexpect DMA address 0x%llx\n",
-                             dma_addr);
-               else if (dma_addr < (2ul << 30))
-                       /* Nothing to do for addresses using BAR0 */
-                       goto done;
-               else if (dma_addr < (2ul << 30) + (128ul << 20))
-                       /* Need to unmap, fall through */
-                       index = (dma_addr - (2ul << 30)) >> 22;
-               else if (dma_addr <
-                        (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20))
-                       goto done;      /* Nothing to do for the rest of BAR1 */
-               else
-                       panic("dma_unmap_single: Unexpect DMA address 0x%llx\n",
-                             dma_addr);
-               /* Continued below switch statement */
+               _octeon_pci_dma_map_ops.phys_to_dma = octeon_big_phys_to_dma;
+               _octeon_pci_dma_map_ops.dma_to_phys = octeon_big_dma_to_phys;
                break;
-
        case OCTEON_DMA_BAR_TYPE_SMALL:
-#ifdef CONFIG_64BIT
-               /* Nothing to do for addresses using BAR2 */
-               if (dma_addr >= BAR2_PCI_ADDRESS)
-                       goto done;
-#endif
-               index = dma_addr >> 22;
-               /* Continued below switch statement */
+               _octeon_pci_dma_map_ops.phys_to_dma = octeon_small_phys_to_dma;
+               _octeon_pci_dma_map_ops.dma_to_phys = octeon_small_dma_to_phys;
                break;
-
        default:
-               panic("dma_unmap_single: Invalid octeon_dma_bar_type\n");
+               BUG();
        }
-
-       if (unlikely(index > 31))
-               panic("dma_unmap_single: "
-                     "Attempt to unmap an invalid address (0x%llx)\n",
-                     dma_addr);
-
-       raw_spin_lock_irqsave(&bar1_lock, flags);
-       bar1_state[index].ref_count--;
-       if (bar1_state[index].ref_count == 0)
-               octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index), 0);
-       else if (unlikely(bar1_state[index].ref_count < 0))
-               panic("dma_unmap_single: Bar1[%u] reference count < 0\n",
-                     (int) index);
-       raw_spin_unlock_irqrestore(&bar1_lock, flags);
-done:
-       pr_debug("dma_unmap_single 0x%llx\n", dma_addr);
-       return;
-#endif
+       octeon_pci_dma_map_ops = &_octeon_pci_dma_map_ops.dma_map_ops;
 }
+#endif /* CONFIG_PCI */
index 6abe56f1e09737055c347a2d064af2a5dc991c37..d38246e33ddb9f1eacb7f885f809db54057c5203 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -26,8 +26,8 @@
  ***********************license end**************************************/
 
 /*
- * Implementation of the Level 2 Cache (L2C) control, measurement, and
- * debugging facilities.
+ * Implementation of the Level 2 Cache (L2C) control,
+ * measurement, and debugging facilities.
  */
 
 #include <asm/octeon/cvmx.h>
  * if multiple applications or operating systems are running, then it
  * is up to the user program to coordinate between them.
  */
-static cvmx_spinlock_t cvmx_l2c_spinlock;
-
-static inline int l2_size_half(void)
-{
-       uint64_t val = cvmx_read_csr(CVMX_L2D_FUS3);
-       return !!(val & (1ull << 34));
-}
+cvmx_spinlock_t cvmx_l2c_spinlock;
 
 int cvmx_l2c_get_core_way_partition(uint32_t core)
 {
@@ -58,6 +52,9 @@ int cvmx_l2c_get_core_way_partition(uint32_t core)
        if (core >= cvmx_octeon_num_cores())
                return -1;
 
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX))
+               return cvmx_read_csr(CVMX_L2C_WPAR_PPX(core)) & 0xffff;
+
        /*
         * Use the lower two bits of the coreNumber to determine the
         * bit offset of the UMSK[] field in the L2C_SPAR register.
@@ -71,17 +68,13 @@ int cvmx_l2c_get_core_way_partition(uint32_t core)
 
        switch (core & 0xC) {
        case 0x0:
-               return (cvmx_read_csr(CVMX_L2C_SPAR0) & (0xFF << field)) >>
-                       field;
+               return (cvmx_read_csr(CVMX_L2C_SPAR0) & (0xFF << field)) >> field;
        case 0x4:
-               return (cvmx_read_csr(CVMX_L2C_SPAR1) & (0xFF << field)) >>
-                       field;
+               return (cvmx_read_csr(CVMX_L2C_SPAR1) & (0xFF << field)) >> field;
        case 0x8:
-               return (cvmx_read_csr(CVMX_L2C_SPAR2) & (0xFF << field)) >>
-                       field;
+               return (cvmx_read_csr(CVMX_L2C_SPAR2) & (0xFF << field)) >> field;
        case 0xC:
-               return (cvmx_read_csr(CVMX_L2C_SPAR3) & (0xFF << field)) >>
-                       field;
+               return (cvmx_read_csr(CVMX_L2C_SPAR3) & (0xFF << field)) >> field;
        }
        return 0;
 }
@@ -95,48 +88,50 @@ int cvmx_l2c_set_core_way_partition(uint32_t core, uint32_t mask)
 
        mask &= valid_mask;
 
-       /* A UMSK setting which blocks all L2C Ways is an error. */
-       if (mask == valid_mask)
+       /* A UMSK setting which blocks all L2C Ways is an error on some chips */
+       if (mask == valid_mask && !OCTEON_IS_MODEL(OCTEON_CN63XX))
                return -1;
 
        /* Validate the core number */
        if (core >= cvmx_octeon_num_cores())
                return -1;
 
-       /* Check to make sure current mask & new mask don't block all ways */
-       if (((mask | cvmx_l2c_get_core_way_partition(core)) & valid_mask) ==
-           valid_mask)
-               return -1;
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+               cvmx_write_csr(CVMX_L2C_WPAR_PPX(core), mask);
+               return 0;
+       }
 
-       /* Use the lower two bits of core to determine the bit offset of the
+       /*
+        * Use the lower two bits of core to determine the bit offset of the
         * UMSK[] field in the L2C_SPAR register.
         */
        field = (core & 0x3) * 8;
 
-       /* Assign the new mask setting to the UMSK[] field in the appropriate
+       /*
+        * Assign the new mask setting to the UMSK[] field in the appropriate
         * L2C_SPAR register based on the core_num.
         *
         */
        switch (core & 0xC) {
        case 0x0:
                cvmx_write_csr(CVMX_L2C_SPAR0,
-                              (cvmx_read_csr(CVMX_L2C_SPAR0) &
-                               ~(0xFF << field)) | mask << field);
+                              (cvmx_read_csr(CVMX_L2C_SPAR0) & ~(0xFF << field)) |
+                              mask << field);
                break;
        case 0x4:
                cvmx_write_csr(CVMX_L2C_SPAR1,
-                              (cvmx_read_csr(CVMX_L2C_SPAR1) &
-                               ~(0xFF << field)) | mask << field);
+                              (cvmx_read_csr(CVMX_L2C_SPAR1) & ~(0xFF << field)) |
+                              mask << field);
                break;
        case 0x8:
                cvmx_write_csr(CVMX_L2C_SPAR2,
-                              (cvmx_read_csr(CVMX_L2C_SPAR2) &
-                               ~(0xFF << field)) | mask << field);
+                              (cvmx_read_csr(CVMX_L2C_SPAR2) & ~(0xFF << field)) |
+                              mask << field);
                break;
        case 0xC:
                cvmx_write_csr(CVMX_L2C_SPAR3,
-                              (cvmx_read_csr(CVMX_L2C_SPAR3) &
-                               ~(0xFF << field)) | mask << field);
+                              (cvmx_read_csr(CVMX_L2C_SPAR3) & ~(0xFF << field)) |
+                              mask << field);
                break;
        }
        return 0;
@@ -146,84 +141,137 @@ int cvmx_l2c_set_hw_way_partition(uint32_t mask)
 {
        uint32_t valid_mask;
 
-       valid_mask = 0xff;
-
-       if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN38XX)) {
-               if (l2_size_half())
-                       valid_mask = 0xf;
-       } else if (l2_size_half())
-               valid_mask = 0x3;
-
+       valid_mask = (0x1 << cvmx_l2c_get_num_assoc()) - 1;
        mask &= valid_mask;
 
-       /* A UMSK setting which blocks all L2C Ways is an error. */
-       if (mask == valid_mask)
-               return -1;
-       /* Check to make sure current mask & new mask don't block all ways */
-       if (((mask | cvmx_l2c_get_hw_way_partition()) & valid_mask) ==
-           valid_mask)
+       /* A UMSK setting which blocks all L2C Ways is an error on some chips */
+       if (mask == valid_mask  && !OCTEON_IS_MODEL(OCTEON_CN63XX))
                return -1;
 
-       cvmx_write_csr(CVMX_L2C_SPAR4,
-                      (cvmx_read_csr(CVMX_L2C_SPAR4) & ~0xFF) | mask);
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX))
+               cvmx_write_csr(CVMX_L2C_WPAR_IOBX(0), mask);
+       else
+               cvmx_write_csr(CVMX_L2C_SPAR4,
+                              (cvmx_read_csr(CVMX_L2C_SPAR4) & ~0xFF) | mask);
        return 0;
 }
 
 int cvmx_l2c_get_hw_way_partition(void)
 {
-       return cvmx_read_csr(CVMX_L2C_SPAR4) & (0xFF);
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX))
+               return cvmx_read_csr(CVMX_L2C_WPAR_IOBX(0)) & 0xffff;
+       else
+               return cvmx_read_csr(CVMX_L2C_SPAR4) & (0xFF);
 }
 
 void cvmx_l2c_config_perf(uint32_t counter, enum cvmx_l2c_event event,
                          uint32_t clear_on_read)
 {
-       union cvmx_l2c_pfctl pfctl;
+       if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
+               union cvmx_l2c_pfctl pfctl;
 
-       pfctl.u64 = cvmx_read_csr(CVMX_L2C_PFCTL);
+               pfctl.u64 = cvmx_read_csr(CVMX_L2C_PFCTL);
 
-       switch (counter) {
-       case 0:
-               pfctl.s.cnt0sel = event;
-               pfctl.s.cnt0ena = 1;
-               if (!cvmx_octeon_is_pass1())
+               switch (counter) {
+               case 0:
+                       pfctl.s.cnt0sel = event;
+                       pfctl.s.cnt0ena = 1;
                        pfctl.s.cnt0rdclr = clear_on_read;
-               break;
-       case 1:
-               pfctl.s.cnt1sel = event;
-               pfctl.s.cnt1ena = 1;
-               if (!cvmx_octeon_is_pass1())
+                       break;
+               case 1:
+                       pfctl.s.cnt1sel = event;
+                       pfctl.s.cnt1ena = 1;
                        pfctl.s.cnt1rdclr = clear_on_read;
-               break;
-       case 2:
-               pfctl.s.cnt2sel = event;
-               pfctl.s.cnt2ena = 1;
-               if (!cvmx_octeon_is_pass1())
+                       break;
+               case 2:
+                       pfctl.s.cnt2sel = event;
+                       pfctl.s.cnt2ena = 1;
                        pfctl.s.cnt2rdclr = clear_on_read;
-               break;
-       case 3:
-       default:
-               pfctl.s.cnt3sel = event;
-               pfctl.s.cnt3ena = 1;
-               if (!cvmx_octeon_is_pass1())
+                       break;
+               case 3:
+               default:
+                       pfctl.s.cnt3sel = event;
+                       pfctl.s.cnt3ena = 1;
                        pfctl.s.cnt3rdclr = clear_on_read;
-               break;
-       }
+                       break;
+               }
 
-       cvmx_write_csr(CVMX_L2C_PFCTL, pfctl.u64);
+               cvmx_write_csr(CVMX_L2C_PFCTL, pfctl.u64);
+       } else {
+               union cvmx_l2c_tadx_prf l2c_tadx_prf;
+               int tad;
+
+               cvmx_dprintf("L2C performance counter events are different for this chip, mapping 'event' to cvmx_l2c_tad_event_t\n");
+               if (clear_on_read)
+                       cvmx_dprintf("L2C counters don't support clear on read for this chip\n");
+
+               l2c_tadx_prf.u64 = cvmx_read_csr(CVMX_L2C_TADX_PRF(0));
+
+               switch (counter) {
+               case 0:
+                       l2c_tadx_prf.s.cnt0sel = event;
+                       break;
+               case 1:
+                       l2c_tadx_prf.s.cnt1sel = event;
+                       break;
+               case 2:
+                       l2c_tadx_prf.s.cnt2sel = event;
+                       break;
+               default:
+               case 3:
+                       l2c_tadx_prf.s.cnt3sel = event;
+                       break;
+               }
+               for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+                       cvmx_write_csr(CVMX_L2C_TADX_PRF(tad),
+                                      l2c_tadx_prf.u64);
+       }
 }
 
 uint64_t cvmx_l2c_read_perf(uint32_t counter)
 {
        switch (counter) {
        case 0:
-               return cvmx_read_csr(CVMX_L2C_PFC0);
+               if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX))
+                       return cvmx_read_csr(CVMX_L2C_PFC0);
+               else {
+                       uint64_t counter = 0;
+                       int tad;
+                       for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+                               counter += cvmx_read_csr(CVMX_L2C_TADX_PFC0(tad));
+                       return counter;
+               }
        case 1:
-               return cvmx_read_csr(CVMX_L2C_PFC1);
+               if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX))
+                       return cvmx_read_csr(CVMX_L2C_PFC1);
+               else {
+                       uint64_t counter = 0;
+                       int tad;
+                       for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+                               counter += cvmx_read_csr(CVMX_L2C_TADX_PFC1(tad));
+                       return counter;
+               }
        case 2:
-               return cvmx_read_csr(CVMX_L2C_PFC2);
+               if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX))
+                       return cvmx_read_csr(CVMX_L2C_PFC2);
+               else {
+                       uint64_t counter = 0;
+                       int tad;
+                       for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+                               counter += cvmx_read_csr(CVMX_L2C_TADX_PFC2(tad));
+                       return counter;
+               }
        case 3:
        default:
-               return cvmx_read_csr(CVMX_L2C_PFC3);
+               if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX))
+                       return cvmx_read_csr(CVMX_L2C_PFC3);
+               else {
+                       uint64_t counter = 0;
+                       int tad;
+                       for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+                               counter += cvmx_read_csr(CVMX_L2C_TADX_PFC3(tad));
+                       return counter;
+               }
        }
 }
 
@@ -240,7 +288,7 @@ static void fault_in(uint64_t addr, int len)
        volatile char dummy;
        /*
         * Adjust addr and length so we get all cache lines even for
-        * small ranges spanning two cache lines
+        * small ranges spanning two cache lines.
         */
        len += addr & CVMX_CACHE_LINE_MASK;
        addr &= ~CVMX_CACHE_LINE_MASK;
@@ -259,67 +307,100 @@ static void fault_in(uint64_t addr, int len)
 
 int cvmx_l2c_lock_line(uint64_t addr)
 {
-       int retval = 0;
-       union cvmx_l2c_dbg l2cdbg;
-       union cvmx_l2c_lckbase lckbase;
-       union cvmx_l2c_lckoff lckoff;
-       union cvmx_l2t_err l2t_err;
-       l2cdbg.u64 = 0;
-       lckbase.u64 = 0;
-       lckoff.u64 = 0;
-
-       cvmx_spinlock_lock(&cvmx_l2c_spinlock);
-
-       /* Clear l2t error bits if set */
-       l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
-       l2t_err.s.lckerr = 1;
-       l2t_err.s.lckerr2 = 1;
-       cvmx_write_csr(CVMX_L2T_ERR, l2t_err.u64);
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+               int shift = CVMX_L2C_TAG_ADDR_ALIAS_SHIFT;
+               uint64_t assoc = cvmx_l2c_get_num_assoc();
+               uint64_t tag = addr >> shift;
+               uint64_t index = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, cvmx_l2c_address_to_index(addr) << CVMX_L2C_IDX_ADDR_SHIFT);
+               uint64_t way;
+               union cvmx_l2c_tadx_tag l2c_tadx_tag;
+
+               CVMX_CACHE_LCKL2(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, addr), 0);
+
+               /* Make sure we were able to lock the line */
+               for (way = 0; way < assoc; way++) {
+                       CVMX_CACHE_LTGL2I(index | (way << shift), 0);
+                       /* make sure CVMX_L2C_TADX_TAG is updated */
+                       CVMX_SYNC;
+                       l2c_tadx_tag.u64 = cvmx_read_csr(CVMX_L2C_TADX_TAG(0));
+                       if (l2c_tadx_tag.s.valid && l2c_tadx_tag.s.tag == tag)
+                               break;
+               }
 
-       addr &= ~CVMX_CACHE_LINE_MASK;
+               /* Check if a valid line is found */
+               if (way >= assoc) {
+                       /* cvmx_dprintf("ERROR: cvmx_l2c_lock_line: line not found for locking at 0x%llx address\n", (unsigned long long)addr); */
+                       return -1;
+               }
 
-       /* Set this core as debug core */
-       l2cdbg.s.ppnum = cvmx_get_core_num();
-       CVMX_SYNC;
-       cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
-       cvmx_read_csr(CVMX_L2C_DBG);
-
-       lckoff.s.lck_offset = 0;        /* Only lock 1 line at a time */
-       cvmx_write_csr(CVMX_L2C_LCKOFF, lckoff.u64);
-       cvmx_read_csr(CVMX_L2C_LCKOFF);
-
-       if (((union cvmx_l2c_cfg) (cvmx_read_csr(CVMX_L2C_CFG))).s.idxalias) {
-               int alias_shift =
-                   CVMX_L2C_IDX_ADDR_SHIFT + 2 * CVMX_L2_SET_BITS - 1;
-               uint64_t addr_tmp =
-                   addr ^ (addr & ((1 << alias_shift) - 1)) >>
-                   CVMX_L2_SET_BITS;
-               lckbase.s.lck_base = addr_tmp >> 7;
+               /* Check if lock bit is not set */
+               if (!l2c_tadx_tag.s.lock) {
+                       /* cvmx_dprintf("ERROR: cvmx_l2c_lock_line: Not able to lock at 0x%llx address\n", (unsigned long long)addr); */
+                       return -1;
+               }
+               return way;
        } else {
-               lckbase.s.lck_base = addr >> 7;
-       }
+               int retval = 0;
+               union cvmx_l2c_dbg l2cdbg;
+               union cvmx_l2c_lckbase lckbase;
+               union cvmx_l2c_lckoff lckoff;
+               union cvmx_l2t_err l2t_err;
 
-       lckbase.s.lck_ena = 1;
-       cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
-       cvmx_read_csr(CVMX_L2C_LCKBASE);        /* Make sure it gets there */
+               cvmx_spinlock_lock(&cvmx_l2c_spinlock);
 
-       fault_in(addr, CVMX_CACHE_LINE_SIZE);
+               l2cdbg.u64 = 0;
+               lckbase.u64 = 0;
+               lckoff.u64 = 0;
 
-       lckbase.s.lck_ena = 0;
-       cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
-       cvmx_read_csr(CVMX_L2C_LCKBASE);        /* Make sure it gets there */
+               /* Clear l2t error bits if set */
+               l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
+               l2t_err.s.lckerr = 1;
+               l2t_err.s.lckerr2 = 1;
+               cvmx_write_csr(CVMX_L2T_ERR, l2t_err.u64);
 
-       /* Stop being debug core */
-       cvmx_write_csr(CVMX_L2C_DBG, 0);
-       cvmx_read_csr(CVMX_L2C_DBG);
+               addr &= ~CVMX_CACHE_LINE_MASK;
 
-       l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
-       if (l2t_err.s.lckerr || l2t_err.s.lckerr2)
-               retval = 1;     /* We were unable to lock the line */
+               /* Set this core as debug core */
+               l2cdbg.s.ppnum = cvmx_get_core_num();
+               CVMX_SYNC;
+               cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
+               cvmx_read_csr(CVMX_L2C_DBG);
+
+               lckoff.s.lck_offset = 0; /* Only lock 1 line at a time */
+               cvmx_write_csr(CVMX_L2C_LCKOFF, lckoff.u64);
+               cvmx_read_csr(CVMX_L2C_LCKOFF);
+
+               if (((union cvmx_l2c_cfg)(cvmx_read_csr(CVMX_L2C_CFG))).s.idxalias) {
+                       int alias_shift = CVMX_L2C_IDX_ADDR_SHIFT + 2 * CVMX_L2_SET_BITS - 1;
+                       uint64_t addr_tmp = addr ^ (addr & ((1 << alias_shift) - 1)) >> CVMX_L2_SET_BITS;
+                       lckbase.s.lck_base = addr_tmp >> 7;
+               } else {
+                       lckbase.s.lck_base = addr >> 7;
+               }
 
-       cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
+               lckbase.s.lck_ena = 1;
+               cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
+               /* Make sure it gets there */
+               cvmx_read_csr(CVMX_L2C_LCKBASE);
 
-       return retval;
+               fault_in(addr, CVMX_CACHE_LINE_SIZE);
+
+               lckbase.s.lck_ena = 0;
+               cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
+               /* Make sure it gets there */
+               cvmx_read_csr(CVMX_L2C_LCKBASE);
+
+               /* Stop being debug core */
+               cvmx_write_csr(CVMX_L2C_DBG, 0);
+               cvmx_read_csr(CVMX_L2C_DBG);
+
+               l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
+               if (l2t_err.s.lckerr || l2t_err.s.lckerr2)
+                       retval = 1;  /* We were unable to lock the line */
+
+               cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
+               return retval;
+       }
 }
 
 int cvmx_l2c_lock_mem_region(uint64_t start, uint64_t len)
@@ -336,7 +417,6 @@ int cvmx_l2c_lock_mem_region(uint64_t start, uint64_t len)
                start += CVMX_CACHE_LINE_SIZE;
                len -= CVMX_CACHE_LINE_SIZE;
        }
-
        return retval;
 }
 
@@ -344,80 +424,73 @@ void cvmx_l2c_flush(void)
 {
        uint64_t assoc, set;
        uint64_t n_assoc, n_set;
-       union cvmx_l2c_dbg l2cdbg;
-
-       cvmx_spinlock_lock(&cvmx_l2c_spinlock);
 
-       l2cdbg.u64 = 0;
-       if (!OCTEON_IS_MODEL(OCTEON_CN30XX))
-               l2cdbg.s.ppnum = cvmx_get_core_num();
-       l2cdbg.s.finv = 1;
-       n_set = CVMX_L2_SETS;
-       n_assoc = l2_size_half() ? (CVMX_L2_ASSOC / 2) : CVMX_L2_ASSOC;
-       for (set = 0; set < n_set; set++) {
-               for (assoc = 0; assoc < n_assoc; assoc++) {
-                       l2cdbg.s.set = assoc;
-                       /* Enter debug mode, and make sure all other
-                        ** writes complete before we enter debug
-                        ** mode */
-                       CVMX_SYNCW;
-                       cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
-                       cvmx_read_csr(CVMX_L2C_DBG);
-
-                       CVMX_PREPARE_FOR_STORE(CVMX_ADD_SEG
-                                              (CVMX_MIPS_SPACE_XKPHYS,
-                                               set * CVMX_CACHE_LINE_SIZE), 0);
-                       CVMX_SYNCW;     /* Push STF out to L2 */
-                       /* Exit debug mode */
-                       CVMX_SYNC;
-                       cvmx_write_csr(CVMX_L2C_DBG, 0);
-                       cvmx_read_csr(CVMX_L2C_DBG);
+       n_set = cvmx_l2c_get_num_sets();
+       n_assoc = cvmx_l2c_get_num_assoc();
+
+       if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+               uint64_t address;
+               /* These may look like constants, but they aren't... */
+               int assoc_shift = CVMX_L2C_TAG_ADDR_ALIAS_SHIFT;
+               int set_shift = CVMX_L2C_IDX_ADDR_SHIFT;
+               for (set = 0; set < n_set; set++) {
+                       for (assoc = 0; assoc < n_assoc; assoc++) {
+                               address = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+                                                      (assoc << assoc_shift) | (set << set_shift));
+                               CVMX_CACHE_WBIL2I(address, 0);
+                       }
                }
+       } else {
+               for (set = 0; set < n_set; set++)
+                       for (assoc = 0; assoc < n_assoc; assoc++)
+                               cvmx_l2c_flush_line(assoc, set);
        }
-
-       cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
 }
 
+
 int cvmx_l2c_unlock_line(uint64_t address)
 {
-       int assoc;
-       union cvmx_l2c_tag tag;
-       union cvmx_l2c_dbg l2cdbg;
-       uint32_t tag_addr;
 
-       uint32_t index = cvmx_l2c_address_to_index(address);
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+               int assoc;
+               union cvmx_l2c_tag tag;
+               uint32_t tag_addr;
+               uint32_t index = cvmx_l2c_address_to_index(address);
+
+               tag_addr = ((address >> CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) & ((1 << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) - 1));
+
+               /*
+                * For 63XX, we can flush a line by using the physical
+                * address directly, so finding the cache line used by
+                * the address is only required to provide the proper
+                * return value for the function.
+                */
+               for (assoc = 0; assoc < CVMX_L2_ASSOC; assoc++) {
+                       tag = cvmx_l2c_get_tag(assoc, index);
+
+                       if (tag.s.V && (tag.s.addr == tag_addr)) {
+                               CVMX_CACHE_WBIL2(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, address), 0);
+                               return tag.s.L;
+                       }
+               }
+       } else {
+               int assoc;
+               union cvmx_l2c_tag tag;
+               uint32_t tag_addr;
 
-       cvmx_spinlock_lock(&cvmx_l2c_spinlock);
-       /* Compute portion of address that is stored in tag */
-       tag_addr =
-           ((address >> CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) &
-            ((1 << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) - 1));
-       for (assoc = 0; assoc < CVMX_L2_ASSOC; assoc++) {
-               tag = cvmx_get_l2c_tag(assoc, index);
+               uint32_t index = cvmx_l2c_address_to_index(address);
 
-               if (tag.s.V && (tag.s.addr == tag_addr)) {
-                       l2cdbg.u64 = 0;
-                       l2cdbg.s.ppnum = cvmx_get_core_num();
-                       l2cdbg.s.set = assoc;
-                       l2cdbg.s.finv = 1;
+               /* Compute portion of address that is stored in tag */
+               tag_addr = ((address >> CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) & ((1 << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) - 1));
+               for (assoc = 0; assoc < CVMX_L2_ASSOC; assoc++) {
+                       tag = cvmx_l2c_get_tag(assoc, index);
 
-                       CVMX_SYNC;
-                       /* Enter debug mode */
-                       cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
-                       cvmx_read_csr(CVMX_L2C_DBG);
-
-                       CVMX_PREPARE_FOR_STORE(CVMX_ADD_SEG
-                                              (CVMX_MIPS_SPACE_XKPHYS,
-                                               address), 0);
-                       CVMX_SYNC;
-                       /* Exit debug mode */
-                       cvmx_write_csr(CVMX_L2C_DBG, 0);
-                       cvmx_read_csr(CVMX_L2C_DBG);
-                       cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
-                       return tag.s.L;
+                       if (tag.s.V && (tag.s.addr == tag_addr)) {
+                               cvmx_l2c_flush_line(assoc, index);
+                               return tag.s.L;
+                       }
                }
        }
-       cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
        return 0;
 }
 
@@ -445,48 +518,49 @@ union __cvmx_l2c_tag {
        uint64_t u64;
        struct cvmx_l2c_tag_cn50xx {
                uint64_t reserved:40;
-               uint64_t V:1;   /* Line valid */
-               uint64_t D:1;   /* Line dirty */
-               uint64_t L:1;   /* Line locked */
-               uint64_t U:1;   /* Use, LRU eviction */
+               uint64_t V:1;           /* Line valid */
+               uint64_t D:1;           /* Line dirty */
+               uint64_t L:1;           /* Line locked */
+               uint64_t U:1;           /* Use, LRU eviction */
                uint64_t addr:20;       /* Phys mem addr (33..14) */
        } cn50xx;
        struct cvmx_l2c_tag_cn30xx {
                uint64_t reserved:41;
-               uint64_t V:1;   /* Line valid */
-               uint64_t D:1;   /* Line dirty */
-               uint64_t L:1;   /* Line locked */
-               uint64_t U:1;   /* Use, LRU eviction */
+               uint64_t V:1;           /* Line valid */
+               uint64_t D:1;           /* Line dirty */
+               uint64_t L:1;           /* Line locked */
+               uint64_t U:1;           /* Use, LRU eviction */
                uint64_t addr:19;       /* Phys mem addr (33..15) */
        } cn30xx;
        struct cvmx_l2c_tag_cn31xx {
                uint64_t reserved:42;
-               uint64_t V:1;   /* Line valid */
-               uint64_t D:1;   /* Line dirty */
-               uint64_t L:1;   /* Line locked */
-               uint64_t U:1;   /* Use, LRU eviction */
+               uint64_t V:1;           /* Line valid */
+               uint64_t D:1;           /* Line dirty */
+               uint64_t L:1;           /* Line locked */
+               uint64_t U:1;           /* Use, LRU eviction */
                uint64_t addr:18;       /* Phys mem addr (33..16) */
        } cn31xx;
        struct cvmx_l2c_tag_cn38xx {
                uint64_t reserved:43;
-               uint64_t V:1;   /* Line valid */
-               uint64_t D:1;   /* Line dirty */
-               uint64_t L:1;   /* Line locked */
-               uint64_t U:1;   /* Use, LRU eviction */
+               uint64_t V:1;           /* Line valid */
+               uint64_t D:1;           /* Line dirty */
+               uint64_t L:1;           /* Line locked */
+               uint64_t U:1;           /* Use, LRU eviction */
                uint64_t addr:17;       /* Phys mem addr (33..17) */
        } cn38xx;
        struct cvmx_l2c_tag_cn58xx {
                uint64_t reserved:44;
-               uint64_t V:1;   /* Line valid */
-               uint64_t D:1;   /* Line dirty */
-               uint64_t L:1;   /* Line locked */
-               uint64_t U:1;   /* Use, LRU eviction */
+               uint64_t V:1;           /* Line valid */
+               uint64_t D:1;           /* Line dirty */
+               uint64_t L:1;           /* Line locked */
+               uint64_t U:1;           /* Use, LRU eviction */
                uint64_t addr:16;       /* Phys mem addr (33..18) */
        } cn58xx;
        struct cvmx_l2c_tag_cn58xx cn56xx;      /* 2048 sets */
        struct cvmx_l2c_tag_cn31xx cn52xx;      /* 512 sets */
 };
 
+
 /**
  * @INTERNAL
  * Function to read a L2C tag.  This code make the current core
@@ -503,7 +577,7 @@ union __cvmx_l2c_tag {
 static union __cvmx_l2c_tag __read_l2_tag(uint64_t assoc, uint64_t index)
 {
 
-       uint64_t debug_tag_addr = (((1ULL << 63) | (index << 7)) + 96);
+       uint64_t debug_tag_addr = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, (index << 7) + 96);
        uint64_t core = cvmx_get_core_num();
        union __cvmx_l2c_tag tag_val;
        uint64_t dbg_addr = CVMX_L2C_DBG;
@@ -512,12 +586,15 @@ static union __cvmx_l2c_tag __read_l2_tag(uint64_t assoc, uint64_t index)
        union cvmx_l2c_dbg debug_val;
        debug_val.u64 = 0;
        /*
-        * For low core count parts, the core number is always small enough
-        * to stay in the correct field and not set any reserved bits.
+        * For low core count parts, the core number is always small
+        * enough to stay in the correct field and not set any
+        * reserved bits.
         */
        debug_val.s.ppnum = core;
        debug_val.s.l2t = 1;
        debug_val.s.set = assoc;
+
+       local_irq_save(flags);
        /*
         * Make sure core is quiet (no prefetches, etc.) before
         * entering debug mode.
@@ -526,112 +603,139 @@ static union __cvmx_l2c_tag __read_l2_tag(uint64_t assoc, uint64_t index)
        /* Flush L1 to make sure debug load misses L1 */
        CVMX_DCACHE_INVALIDATE;
 
-       local_irq_save(flags);
-
        /*
         * The following must be done in assembly as when in debug
         * mode all data loads from L2 return special debug data, not
-        * normal memory contents.  Also, interrupts must be
-        * disabled, since if an interrupt occurs while in debug mode
-        * the ISR will get debug data from all its memory reads
-        * instead of the contents of memory
+        * normal memory contents.  Also, interrupts must be disabled,
+        * since if an interrupt occurs while in debug mode the ISR
+        * will get debug data from all its memory * reads instead of
+        * the contents of memory.
         */
 
-       asm volatile (".set push              \n"
-               "        .set mips64              \n"
-               "        .set noreorder           \n"
-               /* Enter debug mode, wait for store */
-               "        sd    %[dbg_val], 0(%[dbg_addr])  \n"
-               "        ld    $0, 0(%[dbg_addr]) \n"
-               /* Read L2C tag data */
-               "        ld    %[tag_val], 0(%[tag_addr]) \n"
-               /* Exit debug mode, wait for store */
-               "        sd    $0, 0(%[dbg_addr])  \n"
-               "        ld    $0, 0(%[dbg_addr]) \n"
-               /* Invalidate dcache to discard debug data */
-               "        cache 9, 0($0) \n"
-               "        .set pop" :
-               [tag_val] "=r"(tag_val.u64) : [dbg_addr] "r"(dbg_addr),
-               [dbg_val] "r"(debug_val.u64),
-               [tag_addr] "r"(debug_tag_addr) : "memory");
+       asm volatile (
+               ".set push\n\t"
+               ".set mips64\n\t"
+               ".set noreorder\n\t"
+               "sd    %[dbg_val], 0(%[dbg_addr])\n\t"   /* Enter debug mode, wait for store */
+               "ld    $0, 0(%[dbg_addr])\n\t"
+               "ld    %[tag_val], 0(%[tag_addr])\n\t"   /* Read L2C tag data */
+               "sd    $0, 0(%[dbg_addr])\n\t"          /* Exit debug mode, wait for store */
+               "ld    $0, 0(%[dbg_addr])\n\t"
+               "cache 9, 0($0)\n\t"             /* Invalidate dcache to discard debug data */
+               ".set pop"
+               : [tag_val] "=r" (tag_val)
+               : [dbg_addr] "r" (dbg_addr), [dbg_val] "r" (debug_val), [tag_addr] "r" (debug_tag_addr)
+               : "memory");
 
        local_irq_restore(flags);
-       return tag_val;
 
+       return tag_val;
 }
 
+
 union cvmx_l2c_tag cvmx_l2c_get_tag(uint32_t association, uint32_t index)
 {
-       union __cvmx_l2c_tag tmp_tag;
        union cvmx_l2c_tag tag;
        tag.u64 = 0;
 
        if ((int)association >= cvmx_l2c_get_num_assoc()) {
-               cvmx_dprintf
-                   ("ERROR: cvmx_get_l2c_tag association out of range\n");
+               cvmx_dprintf("ERROR: cvmx_l2c_get_tag association out of range\n");
                return tag;
        }
        if ((int)index >= cvmx_l2c_get_num_sets()) {
-               cvmx_dprintf("ERROR: cvmx_get_l2c_tag "
-                            "index out of range (arg: %d, max: %d\n",
-                    index, cvmx_l2c_get_num_sets());
+               cvmx_dprintf("ERROR: cvmx_l2c_get_tag index out of range (arg: %d, max: %d)\n",
+                            (int)index, cvmx_l2c_get_num_sets());
                return tag;
        }
-       /* __read_l2_tag is intended for internal use only */
-       tmp_tag = __read_l2_tag(association, index);
-
-       /*
-        * Convert all tag structure types to generic version, as it
-        * can represent all models.
-        */
-       if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) {
-               tag.s.V = tmp_tag.cn58xx.V;
-               tag.s.D = tmp_tag.cn58xx.D;
-               tag.s.L = tmp_tag.cn58xx.L;
-               tag.s.U = tmp_tag.cn58xx.U;
-               tag.s.addr = tmp_tag.cn58xx.addr;
-       } else if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
-               tag.s.V = tmp_tag.cn38xx.V;
-               tag.s.D = tmp_tag.cn38xx.D;
-               tag.s.L = tmp_tag.cn38xx.L;
-               tag.s.U = tmp_tag.cn38xx.U;
-               tag.s.addr = tmp_tag.cn38xx.addr;
-       } else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
-                  || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
-               tag.s.V = tmp_tag.cn31xx.V;
-               tag.s.D = tmp_tag.cn31xx.D;
-               tag.s.L = tmp_tag.cn31xx.L;
-               tag.s.U = tmp_tag.cn31xx.U;
-               tag.s.addr = tmp_tag.cn31xx.addr;
-       } else if (OCTEON_IS_MODEL(OCTEON_CN30XX)) {
-               tag.s.V = tmp_tag.cn30xx.V;
-               tag.s.D = tmp_tag.cn30xx.D;
-               tag.s.L = tmp_tag.cn30xx.L;
-               tag.s.U = tmp_tag.cn30xx.U;
-               tag.s.addr = tmp_tag.cn30xx.addr;
-       } else if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
-               tag.s.V = tmp_tag.cn50xx.V;
-               tag.s.D = tmp_tag.cn50xx.D;
-               tag.s.L = tmp_tag.cn50xx.L;
-               tag.s.U = tmp_tag.cn50xx.U;
-               tag.s.addr = tmp_tag.cn50xx.addr;
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+               union cvmx_l2c_tadx_tag l2c_tadx_tag;
+               uint64_t address = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+                                               (association << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) |
+                                               (index << CVMX_L2C_IDX_ADDR_SHIFT));
+               /*
+                * Use L2 cache Index load tag cache instruction, as
+                * hardware loads the virtual tag for the L2 cache
+                * block with the contents of L2C_TAD0_TAG
+                * register.
+                */
+               CVMX_CACHE_LTGL2I(address, 0);
+               CVMX_SYNC;   /* make sure CVMX_L2C_TADX_TAG is updated */
+               l2c_tadx_tag.u64 = cvmx_read_csr(CVMX_L2C_TADX_TAG(0));
+
+               tag.s.V     = l2c_tadx_tag.s.valid;
+               tag.s.D     = l2c_tadx_tag.s.dirty;
+               tag.s.L     = l2c_tadx_tag.s.lock;
+               tag.s.U     = l2c_tadx_tag.s.use;
+               tag.s.addr  = l2c_tadx_tag.s.tag;
        } else {
-               cvmx_dprintf("Unsupported OCTEON Model in %s\n", __func__);
+               union __cvmx_l2c_tag tmp_tag;
+               /* __read_l2_tag is intended for internal use only */
+               tmp_tag = __read_l2_tag(association, index);
+
+               /*
+                * Convert all tag structure types to generic version,
+                * as it can represent all models.
+                */
+               if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) {
+                       tag.s.V    = tmp_tag.cn58xx.V;
+                       tag.s.D    = tmp_tag.cn58xx.D;
+                       tag.s.L    = tmp_tag.cn58xx.L;
+                       tag.s.U    = tmp_tag.cn58xx.U;
+                       tag.s.addr = tmp_tag.cn58xx.addr;
+               } else if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
+                       tag.s.V    = tmp_tag.cn38xx.V;
+                       tag.s.D    = tmp_tag.cn38xx.D;
+                       tag.s.L    = tmp_tag.cn38xx.L;
+                       tag.s.U    = tmp_tag.cn38xx.U;
+                       tag.s.addr = tmp_tag.cn38xx.addr;
+               } else if (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+                       tag.s.V    = tmp_tag.cn31xx.V;
+                       tag.s.D    = tmp_tag.cn31xx.D;
+                       tag.s.L    = tmp_tag.cn31xx.L;
+                       tag.s.U    = tmp_tag.cn31xx.U;
+                       tag.s.addr = tmp_tag.cn31xx.addr;
+               } else if (OCTEON_IS_MODEL(OCTEON_CN30XX)) {
+                       tag.s.V    = tmp_tag.cn30xx.V;
+                       tag.s.D    = tmp_tag.cn30xx.D;
+                       tag.s.L    = tmp_tag.cn30xx.L;
+                       tag.s.U    = tmp_tag.cn30xx.U;
+                       tag.s.addr = tmp_tag.cn30xx.addr;
+               } else if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
+                       tag.s.V    = tmp_tag.cn50xx.V;
+                       tag.s.D    = tmp_tag.cn50xx.D;
+                       tag.s.L    = tmp_tag.cn50xx.L;
+                       tag.s.U    = tmp_tag.cn50xx.U;
+                       tag.s.addr = tmp_tag.cn50xx.addr;
+               } else {
+                       cvmx_dprintf("Unsupported OCTEON Model in %s\n", __func__);
+               }
        }
-
        return tag;
 }
 
 uint32_t cvmx_l2c_address_to_index(uint64_t addr)
 {
        uint64_t idx = addr >> CVMX_L2C_IDX_ADDR_SHIFT;
-       union cvmx_l2c_cfg l2c_cfg;
-       l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
+       int indxalias = 0;
 
-       if (l2c_cfg.s.idxalias) {
-               idx ^=
-                   ((addr & CVMX_L2C_ALIAS_MASK) >>
-                    CVMX_L2C_TAG_ADDR_ALIAS_SHIFT);
+       if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+               union cvmx_l2c_ctl l2c_ctl;
+               l2c_ctl.u64 = cvmx_read_csr(CVMX_L2C_CTL);
+               indxalias = !l2c_ctl.s.disidxalias;
+       } else {
+               union cvmx_l2c_cfg l2c_cfg;
+               l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
+               indxalias = l2c_cfg.s.idxalias;
+       }
+
+       if (indxalias) {
+               if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+                       uint32_t a_14_12 = (idx / (CVMX_L2C_MEMBANK_SELECT_SIZE/(1<<CVMX_L2C_IDX_ADDR_SHIFT))) & 0x7;
+                       idx ^= idx / cvmx_l2c_get_num_sets();
+                       idx ^= a_14_12;
+               } else {
+                       idx ^= ((addr & CVMX_L2C_ALIAS_MASK) >> CVMX_L2C_TAG_ADDR_ALIAS_SHIFT);
+               }
        }
        idx &= CVMX_L2C_IDX_MASK;
        return idx;
@@ -652,10 +756,9 @@ int cvmx_l2c_get_set_bits(void)
        int l2_set_bits;
        if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
                l2_set_bits = 11;       /* 2048 sets */
-       else if (OCTEON_IS_MODEL(OCTEON_CN38XX))
+       else if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN63XX))
                l2_set_bits = 10;       /* 1024 sets */
-       else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
-                || OCTEON_IS_MODEL(OCTEON_CN52XX))
+       else if (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
                l2_set_bits = 9;        /* 512 sets */
        else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
                l2_set_bits = 8;        /* 256 sets */
@@ -666,7 +769,6 @@ int cvmx_l2c_get_set_bits(void)
                l2_set_bits = 11;       /* 2048 sets */
        }
        return l2_set_bits;
-
 }
 
 /* Return the number of sets in the L2 Cache */
@@ -682,8 +784,11 @@ int cvmx_l2c_get_num_assoc(void)
        if (OCTEON_IS_MODEL(OCTEON_CN56XX) ||
            OCTEON_IS_MODEL(OCTEON_CN52XX) ||
            OCTEON_IS_MODEL(OCTEON_CN58XX) ||
-           OCTEON_IS_MODEL(OCTEON_CN50XX) || OCTEON_IS_MODEL(OCTEON_CN38XX))
+           OCTEON_IS_MODEL(OCTEON_CN50XX) ||
+           OCTEON_IS_MODEL(OCTEON_CN38XX))
                l2_assoc = 8;
+       else if (OCTEON_IS_MODEL(OCTEON_CN63XX))
+               l2_assoc = 16;
        else if (OCTEON_IS_MODEL(OCTEON_CN31XX) ||
                 OCTEON_IS_MODEL(OCTEON_CN30XX))
                l2_assoc = 4;
@@ -693,11 +798,42 @@ int cvmx_l2c_get_num_assoc(void)
        }
 
        /* Check to see if part of the cache is disabled */
-       if (cvmx_fuse_read(265))
-               l2_assoc = l2_assoc >> 2;
-       else if (cvmx_fuse_read(264))
-               l2_assoc = l2_assoc >> 1;
-
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+               union cvmx_mio_fus_dat3 mio_fus_dat3;
+
+               mio_fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3);
+               /*
+                * cvmx_mio_fus_dat3.s.l2c_crip fuses map as follows
+                * <2> will be not used for 63xx
+                * <1> disables 1/2 ways
+                * <0> disables 1/4 ways
+                * They are cumulative, so for 63xx:
+                * <1> <0>
+                * 0 0 16-way 2MB cache
+                * 0 1 12-way 1.5MB cache
+                * 1 0 8-way 1MB cache
+                * 1 1 4-way 512KB cache
+                */
+
+               if (mio_fus_dat3.s.l2c_crip == 3)
+                       l2_assoc = 4;
+               else if (mio_fus_dat3.s.l2c_crip == 2)
+                       l2_assoc = 8;
+               else if (mio_fus_dat3.s.l2c_crip == 1)
+                       l2_assoc = 12;
+       } else {
+               union cvmx_l2d_fus3 val;
+               val.u64 = cvmx_read_csr(CVMX_L2D_FUS3);
+               /*
+                * Using shifts here, as bit position names are
+                * different for each model but they all mean the
+                * same.
+                */
+               if ((val.u64 >> 35) & 0x1)
+                       l2_assoc = l2_assoc >> 2;
+               else if ((val.u64 >> 34) & 0x1)
+                       l2_assoc = l2_assoc >> 1;
+       }
        return l2_assoc;
 }
 
@@ -711,24 +847,54 @@ int cvmx_l2c_get_num_assoc(void)
  */
 void cvmx_l2c_flush_line(uint32_t assoc, uint32_t index)
 {
-       union cvmx_l2c_dbg l2cdbg;
+       /* Check the range of the index. */
+       if (index > (uint32_t)cvmx_l2c_get_num_sets()) {
+               cvmx_dprintf("ERROR: cvmx_l2c_flush_line index out of range.\n");
+               return;
+       }
 
-       l2cdbg.u64 = 0;
-       l2cdbg.s.ppnum = cvmx_get_core_num();
-       l2cdbg.s.finv = 1;
+       /* Check the range of association. */
+       if (assoc > (uint32_t)cvmx_l2c_get_num_assoc()) {
+               cvmx_dprintf("ERROR: cvmx_l2c_flush_line association out of range.\n");
+               return;
+       }
 
-       l2cdbg.s.set = assoc;
-       /*
-        * Enter debug mode, and make sure all other writes complete
-        * before we enter debug mode.
-        */
-       asm volatile ("sync" : : : "memory");
-       cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
-       cvmx_read_csr(CVMX_L2C_DBG);
-
-       CVMX_PREPARE_FOR_STORE(((1ULL << 63) + (index) * 128), 0);
-       /* Exit debug mode */
-       asm volatile ("sync" : : : "memory");
-       cvmx_write_csr(CVMX_L2C_DBG, 0);
-       cvmx_read_csr(CVMX_L2C_DBG);
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+               uint64_t address;
+               /* Create the address based on index and association.
+                * Bits<20:17> select the way of the cache block involved in
+                *             the operation
+                * Bits<16:7> of the effect address select the index
+                */
+               address = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+                               (assoc << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) |
+                               (index << CVMX_L2C_IDX_ADDR_SHIFT));
+               CVMX_CACHE_WBIL2I(address, 0);
+       } else {
+               union cvmx_l2c_dbg l2cdbg;
+
+               l2cdbg.u64 = 0;
+               if (!OCTEON_IS_MODEL(OCTEON_CN30XX))
+                       l2cdbg.s.ppnum = cvmx_get_core_num();
+               l2cdbg.s.finv = 1;
+
+               l2cdbg.s.set = assoc;
+               cvmx_spinlock_lock(&cvmx_l2c_spinlock);
+               /*
+                * Enter debug mode, and make sure all other writes
+                * complete before we enter debug mode
+                */
+               CVMX_SYNC;
+               cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
+               cvmx_read_csr(CVMX_L2C_DBG);
+
+               CVMX_PREPARE_FOR_STORE(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+                                                   index * CVMX_CACHE_LINE_SIZE),
+                                      0);
+               /* Exit debug mode */
+               CVMX_SYNC;
+               cvmx_write_csr(CVMX_L2C_DBG, 0);
+               cvmx_read_csr(CVMX_L2C_DBG);
+               cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
+       }
 }
index 62ac30eef5e8a1ff5dfac8bfdbf94e846a52b6e0..cecaf62aef32c59322553983003c34dc71a98fa0 100644 (file)
@@ -3,13 +3,15 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2004-2009 Cavium Networks
+ * Copyright (C) 2004-2010 Cavium Networks
  * Copyright (C) 2008 Wind River Systems
  */
 
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/i2c.h>
+#include <linux/usb.h>
+#include <linux/dma-mapping.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
@@ -198,7 +200,7 @@ static int __init octeon_i2c_device_init(void)
                num_ports = 1;
 
        for (port = 0; port < num_ports; port++) {
-               octeon_i2c_data[port].sys_freq = octeon_get_clock_rate();
+               octeon_i2c_data[port].sys_freq = octeon_get_io_clock_rate();
                /*FIXME: should be examined. At the moment is set for 100Khz */
                octeon_i2c_data[port].i2c_freq = 100000;
 
@@ -301,6 +303,10 @@ static int __init octeon_mgmt_device_init(void)
                        ret = -ENOMEM;
                        goto out;
                }
+               /* No DMA restrictions */
+               pd->dev.coherent_dma_mask = DMA_BIT_MASK(64);
+               pd->dev.dma_mask = &pd->dev.coherent_dma_mask;
+
                switch (port) {
                case 0:
                        mgmt_port_resource.start = OCTEON_IRQ_MII0;
@@ -332,6 +338,108 @@ out:
 }
 device_initcall(octeon_mgmt_device_init);
 
+#ifdef CONFIG_USB
+
+static int __init octeon_ehci_device_init(void)
+{
+       struct platform_device *pd;
+       int ret = 0;
+
+       struct resource usb_resources[] = {
+               {
+                       .flags  = IORESOURCE_MEM,
+               }, {
+                       .flags  = IORESOURCE_IRQ,
+               }
+       };
+
+       /* Only Octeon2 has ehci/ohci */
+       if (!OCTEON_IS_MODEL(OCTEON_CN63XX))
+               return 0;
+
+       if (octeon_is_simulation() || usb_disabled())
+               return 0; /* No USB in the simulator. */
+
+       pd = platform_device_alloc("octeon-ehci", 0);
+       if (!pd) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       usb_resources[0].start = 0x00016F0000000000ULL;
+       usb_resources[0].end = usb_resources[0].start + 0x100;
+
+       usb_resources[1].start = OCTEON_IRQ_USB0;
+       usb_resources[1].end = OCTEON_IRQ_USB0;
+
+       ret = platform_device_add_resources(pd, usb_resources,
+                                           ARRAY_SIZE(usb_resources));
+       if (ret)
+               goto fail;
+
+       ret = platform_device_add(pd);
+       if (ret)
+               goto fail;
+
+       return ret;
+fail:
+       platform_device_put(pd);
+out:
+       return ret;
+}
+device_initcall(octeon_ehci_device_init);
+
+static int __init octeon_ohci_device_init(void)
+{
+       struct platform_device *pd;
+       int ret = 0;
+
+       struct resource usb_resources[] = {
+               {
+                       .flags  = IORESOURCE_MEM,
+               }, {
+                       .flags  = IORESOURCE_IRQ,
+               }
+       };
+
+       /* Only Octeon2 has ehci/ohci */
+       if (!OCTEON_IS_MODEL(OCTEON_CN63XX))
+               return 0;
+
+       if (octeon_is_simulation() || usb_disabled())
+               return 0; /* No USB in the simulator. */
+
+       pd = platform_device_alloc("octeon-ohci", 0);
+       if (!pd) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       usb_resources[0].start = 0x00016F0000000400ULL;
+       usb_resources[0].end = usb_resources[0].start + 0x100;
+
+       usb_resources[1].start = OCTEON_IRQ_USB0;
+       usb_resources[1].end = OCTEON_IRQ_USB0;
+
+       ret = platform_device_add_resources(pd, usb_resources,
+                                           ARRAY_SIZE(usb_resources));
+       if (ret)
+               goto fail;
+
+       ret = platform_device_add(pd);
+       if (ret)
+               goto fail;
+
+       return ret;
+fail:
+       platform_device_put(pd);
+out:
+       return ret;
+}
+device_initcall(octeon_ohci_device_init);
+
+#endif /* CONFIG_USB */
+
 MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Platform driver for Octeon SOC");
index 12dbf533b77dc2da263c4e0bfe9e4c2fa86c51d8..057f0ae88c994e6052892d4fc44620c0da7d26fa 100644 (file)
@@ -66,7 +66,7 @@ static void __init octeon_uart_set_common(struct plat_serial8250_port *p)
                /* Make simulator output fast*/
                p->uartclk = 115200 * 16;
        else
-               p->uartclk = mips_hpt_frequency;
+               p->uartclk = octeon_get_io_clock_rate();
        p->serial_in = octeon_serial_in;
        p->serial_out = octeon_serial_out;
 }
index 69197cb6c7ea106349a23ad5b81f615a8c70c614..b0c3686c96dd614abe8dac92a3a84a04818c2e7c 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <asm/octeon/octeon.h>
 #include <asm/octeon/pci-octeon.h>
+#include <asm/octeon/cvmx-mio-defs.h>
 
 #ifdef CONFIG_CAVIUM_DECODE_RSL
 extern void cvmx_interrupt_rsl_decode(void);
@@ -96,12 +97,21 @@ int octeon_is_pci_host(void)
  */
 uint64_t octeon_get_clock_rate(void)
 {
-       if (octeon_is_simulation())
-               octeon_bootinfo->eclock_hz = 6000000;
-       return octeon_bootinfo->eclock_hz;
+       struct cvmx_sysinfo *sysinfo = cvmx_sysinfo_get();
+
+       return sysinfo->cpu_clock_hz;
 }
 EXPORT_SYMBOL(octeon_get_clock_rate);
 
+static u64 octeon_io_clock_rate;
+
+u64 octeon_get_io_clock_rate(void)
+{
+       return octeon_io_clock_rate;
+}
+EXPORT_SYMBOL(octeon_get_io_clock_rate);
+
+
 /**
  * Write to the LCD display connected to the bootbus. This display
  * exists on most Cavium evaluation boards. If it doesn't exist, then
@@ -346,8 +356,18 @@ void octeon_user_io_init(void)
        cvmmemctl.s.wbfltime = 0;
        /* R/W If set, do not put Istream in the L2 cache. */
        cvmmemctl.s.istrnol2 = 0;
-       /* R/W The write buffer threshold. */
-       cvmmemctl.s.wbthresh = 10;
+
+       /*
+        * R/W The write buffer threshold. As per erratum Core-14752
+        * for CN63XX, a sc/scd might fail if the write buffer is
+        * full.  Lowering WBTHRESH greatly lowers the chances of the
+        * write buffer ever being full and triggering the erratum.
+        */
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
+               cvmmemctl.s.wbthresh = 4;
+       else
+               cvmmemctl.s.wbthresh = 10;
+
        /* R/W If set, CVMSEG is available for loads/stores in
         * kernel/debug mode. */
 #if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
@@ -365,14 +385,13 @@ void octeon_user_io_init(void)
         * is max legal value. */
        cvmmemctl.s.lmemsz = CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE;
 
+       write_c0_cvmmemctl(cvmmemctl.u64);
 
        if (smp_processor_id() == 0)
                pr_notice("CVMSEG size: %d cache lines (%d bytes)\n",
                          CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE,
                          CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128);
 
-       write_c0_cvmmemctl(cvmmemctl.u64);
-
        /* Move the performance counter interrupts to IRQ 6 */
        cvmctl = read_c0_cvmctl();
        cvmctl &= ~(7 << 7);
@@ -416,6 +435,41 @@ void __init prom_init(void)
                cvmx_phys_to_ptr(octeon_boot_desc_ptr->cvmx_desc_vaddr);
        cvmx_bootmem_init(cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr));
 
+       sysinfo = cvmx_sysinfo_get();
+       memset(sysinfo, 0, sizeof(*sysinfo));
+       sysinfo->system_dram_size = octeon_bootinfo->dram_size << 20;
+       sysinfo->phy_mem_desc_ptr =
+               cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr);
+       sysinfo->core_mask = octeon_bootinfo->core_mask;
+       sysinfo->exception_base_addr = octeon_bootinfo->exception_base_addr;
+       sysinfo->cpu_clock_hz = octeon_bootinfo->eclock_hz;
+       sysinfo->dram_data_rate_hz = octeon_bootinfo->dclock_hz * 2;
+       sysinfo->board_type = octeon_bootinfo->board_type;
+       sysinfo->board_rev_major = octeon_bootinfo->board_rev_major;
+       sysinfo->board_rev_minor = octeon_bootinfo->board_rev_minor;
+       memcpy(sysinfo->mac_addr_base, octeon_bootinfo->mac_addr_base,
+              sizeof(sysinfo->mac_addr_base));
+       sysinfo->mac_addr_count = octeon_bootinfo->mac_addr_count;
+       memcpy(sysinfo->board_serial_number,
+              octeon_bootinfo->board_serial_number,
+              sizeof(sysinfo->board_serial_number));
+       sysinfo->compact_flash_common_base_addr =
+               octeon_bootinfo->compact_flash_common_base_addr;
+       sysinfo->compact_flash_attribute_base_addr =
+               octeon_bootinfo->compact_flash_attribute_base_addr;
+       sysinfo->led_display_base_addr = octeon_bootinfo->led_display_base_addr;
+       sysinfo->dfa_ref_clock_hz = octeon_bootinfo->dfa_ref_clock_hz;
+       sysinfo->bootloader_config_flags = octeon_bootinfo->config_flags;
+
+       if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+               /* I/O clock runs at a different rate than the CPU. */
+               union cvmx_mio_rst_boot rst_boot;
+               rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
+               octeon_io_clock_rate = 50000000 * rst_boot.s.pnr_mul;
+       } else {
+               octeon_io_clock_rate = sysinfo->cpu_clock_hz;
+       }
+
        /*
         * Only enable the LED controller if we're running on a CN38XX, CN58XX,
         * or CN56XX. The CN30XX and CN31XX don't have an LED controller.
@@ -479,33 +533,6 @@ void __init prom_init(void)
        }
 #endif
 
-       sysinfo = cvmx_sysinfo_get();
-       memset(sysinfo, 0, sizeof(*sysinfo));
-       sysinfo->system_dram_size = octeon_bootinfo->dram_size << 20;
-       sysinfo->phy_mem_desc_ptr =
-               cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr);
-       sysinfo->core_mask = octeon_bootinfo->core_mask;
-       sysinfo->exception_base_addr = octeon_bootinfo->exception_base_addr;
-       sysinfo->cpu_clock_hz = octeon_bootinfo->eclock_hz;
-       sysinfo->dram_data_rate_hz = octeon_bootinfo->dclock_hz * 2;
-       sysinfo->board_type = octeon_bootinfo->board_type;
-       sysinfo->board_rev_major = octeon_bootinfo->board_rev_major;
-       sysinfo->board_rev_minor = octeon_bootinfo->board_rev_minor;
-       memcpy(sysinfo->mac_addr_base, octeon_bootinfo->mac_addr_base,
-              sizeof(sysinfo->mac_addr_base));
-       sysinfo->mac_addr_count = octeon_bootinfo->mac_addr_count;
-       memcpy(sysinfo->board_serial_number,
-              octeon_bootinfo->board_serial_number,
-              sizeof(sysinfo->board_serial_number));
-       sysinfo->compact_flash_common_base_addr =
-               octeon_bootinfo->compact_flash_common_base_addr;
-       sysinfo->compact_flash_attribute_base_addr =
-               octeon_bootinfo->compact_flash_attribute_base_addr;
-       sysinfo->led_display_base_addr = octeon_bootinfo->led_display_base_addr;
-       sysinfo->dfa_ref_clock_hz = octeon_bootinfo->dfa_ref_clock_hz;
-       sysinfo->bootloader_config_flags = octeon_bootinfo->config_flags;
-
-
        octeon_check_cpu_bist();
 
        octeon_uart = octeon_get_boot_uart();
@@ -740,6 +767,31 @@ EXPORT_SYMBOL(prom_putchar);
 
 void prom_free_prom_memory(void)
 {
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X)) {
+               /* Check for presence of Core-14449 fix.  */
+               u32 insn;
+               u32 *foo;
+
+               foo = &insn;
+
+               asm volatile("# before" : : : "memory");
+               prefetch(foo);
+               asm volatile(
+                       ".set push\n\t"
+                       ".set noreorder\n\t"
+                       "bal 1f\n\t"
+                       "nop\n"
+                       "1:\tlw %0,-12($31)\n\t"
+                       ".set pop\n\t"
+                       : "=r" (insn) : : "$31", "memory");
+
+               if ((insn >> 26) != 0x33)
+                       panic("No PREF instruction at Core-14449 probe point.\n");
+
+               if (((insn >> 16) & 0x1f) != 28)
+                       panic("Core-14449 WAR not in place (%04x).\n"
+                             "Please build kernel with proper options (CONFIG_CAVIUM_CN63XXP1).\n", insn);
+       }
 #ifdef CONFIG_CAVIUM_DECODE_RSL
        cvmx_interrupt_rsl_enable();
 
index 47d87da379f947c8a578f2a2b84e7da804f559a8..4a02fe891ab6d5909b11997d738010844f710637 100644 (file)
@@ -64,18 +64,16 @@ static __inline__ void atomic_add(int i, atomic_t * v)
        } else if (kernel_uses_llsc) {
                int temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     ll      %0, %1          # atomic_add            \n"
-               "       addu    %0, %2                                  \n"
-               "       sc      %0, %1                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter));
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       ll      %0, %1          # atomic_add    \n"
+                       "       addu    %0, %2                          \n"
+                       "       sc      %0, %1                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "=m" (v->counter)
+                       : "Ir" (i), "m" (v->counter));
+               } while (unlikely(!temp));
        } else {
                unsigned long flags;
 
@@ -109,18 +107,16 @@ static __inline__ void atomic_sub(int i, atomic_t * v)
        } else if (kernel_uses_llsc) {
                int temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     ll      %0, %1          # atomic_sub            \n"
-               "       subu    %0, %2                                  \n"
-               "       sc      %0, %1                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter));
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       ll      %0, %1          # atomic_sub    \n"
+                       "       subu    %0, %2                          \n"
+                       "       sc      %0, %1                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "=m" (v->counter)
+                       : "Ir" (i), "m" (v->counter));
+               } while (unlikely(!temp));
        } else {
                unsigned long flags;
 
@@ -156,20 +152,19 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
        } else if (kernel_uses_llsc) {
                int temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     ll      %1, %2          # atomic_add_return     \n"
-               "       addu    %0, %1, %3                              \n"
-               "       sc      %0, %2                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       addu    %0, %1, %3                              \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       ll      %1, %2  # atomic_add_return     \n"
+                       "       addu    %0, %1, %3                      \n"
+                       "       sc      %0, %2                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+                       : "Ir" (i), "m" (v->counter)
+                       : "memory");
+               } while (unlikely(!result));
+
+               result = temp + i;
        } else {
                unsigned long flags;
 
@@ -205,23 +200,24 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
                : "memory");
+
+               result = temp - i;
        } else if (kernel_uses_llsc) {
                int temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     ll      %1, %2          # atomic_sub_return     \n"
-               "       subu    %0, %1, %3                              \n"
-               "       sc      %0, %2                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       subu    %0, %1, %3                              \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       ll      %1, %2  # atomic_sub_return     \n"
+                       "       subu    %0, %1, %3                      \n"
+                       "       sc      %0, %2                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+                       : "Ir" (i), "m" (v->counter)
+                       : "memory");
+               } while (unlikely(!result));
+
+               result = temp - i;
        } else {
                unsigned long flags;
 
@@ -279,12 +275,9 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
                "       bltz    %0, 1f                                  \n"
                "       sc      %0, %2                                  \n"
                "       .set    noreorder                               \n"
-               "       beqz    %0, 2f                                  \n"
+               "       beqz    %0, 1b                                  \n"
                "        subu   %0, %1, %3                              \n"
                "       .set    reorder                                 \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
                "1:                                                     \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
@@ -443,18 +436,16 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
        } else if (kernel_uses_llsc) {
                long temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     lld     %0, %1          # atomic64_add          \n"
-               "       daddu   %0, %2                                  \n"
-               "       scd     %0, %1                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter));
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       lld     %0, %1          # atomic64_add  \n"
+                       "       daddu   %0, %2                          \n"
+                       "       scd     %0, %1                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "=m" (v->counter)
+                       : "Ir" (i), "m" (v->counter));
+               } while (unlikely(!temp));
        } else {
                unsigned long flags;
 
@@ -488,18 +479,16 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
        } else if (kernel_uses_llsc) {
                long temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     lld     %0, %1          # atomic64_sub          \n"
-               "       dsubu   %0, %2                                  \n"
-               "       scd     %0, %1                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter));
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       lld     %0, %1          # atomic64_sub  \n"
+                       "       dsubu   %0, %2                          \n"
+                       "       scd     %0, %1                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "=m" (v->counter)
+                       : "Ir" (i), "m" (v->counter));
+               } while (unlikely(!temp));
        } else {
                unsigned long flags;
 
@@ -535,20 +524,19 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
        } else if (kernel_uses_llsc) {
                long temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     lld     %1, %2          # atomic64_add_return   \n"
-               "       daddu   %0, %1, %3                              \n"
-               "       scd     %0, %2                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       daddu   %0, %1, %3                              \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       lld     %1, %2  # atomic64_add_return   \n"
+                       "       daddu   %0, %1, %3                      \n"
+                       "       scd     %0, %2                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+                       : "Ir" (i), "m" (v->counter)
+                       : "memory");
+               } while (unlikely(!result));
+
+               result = temp + i;
        } else {
                unsigned long flags;
 
@@ -587,20 +575,19 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
        } else if (kernel_uses_llsc) {
                long temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     lld     %1, %2          # atomic64_sub_return   \n"
-               "       dsubu   %0, %1, %3                              \n"
-               "       scd     %0, %2                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       dsubu   %0, %1, %3                              \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       lld     %1, %2  # atomic64_sub_return   \n"
+                       "       dsubu   %0, %1, %3                      \n"
+                       "       scd     %0, %2                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+                       : "Ir" (i), "m" (v->counter)
+                       : "memory");
+               } while (unlikely(!result));
+
+               result = temp - i;
        } else {
                unsigned long flags;
 
@@ -658,12 +645,9 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
                "       bltz    %0, 1f                                  \n"
                "       scd     %0, %2                                  \n"
                "       .set    noreorder                               \n"
-               "       beqz    %0, 2f                                  \n"
+               "       beqz    %0, 1b                                  \n"
                "        dsubu  %0, %1, %3                              \n"
                "       .set    reorder                                 \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
                "1:                                                     \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
index b0ce7ca2851f8fc32413e407942cc7367d6643d9..50b4ef288c53f0be1a78d9de79e40e2337a3f76d 100644 (file)
@@ -73,30 +73,26 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
                : "ir" (1UL << bit), "m" (*m));
 #ifdef CONFIG_CPU_MIPSR2
        } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
-               __asm__ __volatile__(
-               "1:     " __LL "%0, %1                  # set_bit       \n"
-               "       " __INS "%0, %4, %2, 1                          \n"
-               "       " __SC "%0, %1                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               : "=&r" (temp), "=m" (*m)
-               : "ir" (bit), "m" (*m), "r" (~0));
+               do {
+                       __asm__ __volatile__(
+                       "       " __LL "%0, %1          # set_bit       \n"
+                       "       " __INS "%0, %3, %2, 1                  \n"
+                       "       " __SC "%0, %1                          \n"
+                       : "=&r" (temp), "+m" (*m)
+                       : "ir" (bit), "r" (~0));
+               } while (unlikely(!temp));
 #endif /* CONFIG_CPU_MIPSR2 */
        } else if (kernel_uses_llsc) {
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     " __LL "%0, %1                  # set_bit       \n"
-               "       or      %0, %2                                  \n"
-               "       " __SC  "%0, %1                                 \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (*m)
-               : "ir" (1UL << bit), "m" (*m));
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       " __LL "%0, %1          # set_bit       \n"
+                       "       or      %0, %2                          \n"
+                       "       " __SC  "%0, %1                         \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "+m" (*m)
+                       : "ir" (1UL << bit));
+               } while (unlikely(!temp));
        } else {
                volatile unsigned long *a = addr;
                unsigned long mask;
@@ -134,34 +130,30 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
                "       " __SC "%0, %1                                  \n"
                "       beqzl   %0, 1b                                  \n"
                "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (*m)
-               : "ir" (~(1UL << bit)), "m" (*m));
+               : "=&r" (temp), "+m" (*m)
+               : "ir" (~(1UL << bit)));
 #ifdef CONFIG_CPU_MIPSR2
        } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
-               __asm__ __volatile__(
-               "1:     " __LL "%0, %1                  # clear_bit     \n"
-               "       " __INS "%0, $0, %2, 1                          \n"
-               "       " __SC "%0, %1                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               : "=&r" (temp), "=m" (*m)
-               : "ir" (bit), "m" (*m));
+               do {
+                       __asm__ __volatile__(
+                       "       " __LL "%0, %1          # clear_bit     \n"
+                       "       " __INS "%0, $0, %2, 1                  \n"
+                       "       " __SC "%0, %1                          \n"
+                       : "=&r" (temp), "+m" (*m)
+                       : "ir" (bit));
+               } while (unlikely(!temp));
 #endif /* CONFIG_CPU_MIPSR2 */
        } else if (kernel_uses_llsc) {
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     " __LL "%0, %1                  # clear_bit     \n"
-               "       and     %0, %2                                  \n"
-               "       " __SC "%0, %1                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (*m)
-               : "ir" (~(1UL << bit)), "m" (*m));
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       " __LL "%0, %1          # clear_bit     \n"
+                       "       and     %0, %2                          \n"
+                       "       " __SC "%0, %1                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "+m" (*m)
+                       : "ir" (~(1UL << bit)));
+               } while (unlikely(!temp));
        } else {
                volatile unsigned long *a = addr;
                unsigned long mask;
@@ -213,24 +205,22 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
                "       " __SC  "%0, %1                         \n"
                "       beqzl   %0, 1b                          \n"
                "       .set    mips0                           \n"
-               : "=&r" (temp), "=m" (*m)
-               : "ir" (1UL << bit), "m" (*m));
+               : "=&r" (temp), "+m" (*m)
+               : "ir" (1UL << bit));
        } else if (kernel_uses_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                           \n"
-               "1:     " __LL "%0, %1          # change_bit    \n"
-               "       xor     %0, %2                          \n"
-               "       " __SC  "%0, %1                         \n"
-               "       beqz    %0, 2f                          \n"
-               "       .subsection 2                           \n"
-               "2:     b       1b                              \n"
-               "       .previous                               \n"
-               "       .set    mips0                           \n"
-               : "=&r" (temp), "=m" (*m)
-               : "ir" (1UL << bit), "m" (*m));
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       " __LL "%0, %1          # change_bit    \n"
+                       "       xor     %0, %2                          \n"
+                       "       " __SC  "%0, %1                         \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "+m" (*m)
+                       : "ir" (1UL << bit));
+               } while (unlikely(!temp));
        } else {
                volatile unsigned long *a = addr;
                unsigned long mask;
@@ -272,30 +262,26 @@ static inline int test_and_set_bit(unsigned long nr,
                "       beqzl   %2, 1b                                  \n"
                "       and     %2, %0, %3                              \n"
                "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "r" (1UL << bit), "m" (*m)
+               : "=&r" (temp), "+m" (*m), "=&r" (res)
+               : "r" (1UL << bit)
                : "memory");
        } else if (kernel_uses_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
-               __asm__ __volatile__(
-               "       .set    push                                    \n"
-               "       .set    noreorder                               \n"
-               "       .set    mips3                                   \n"
-               "1:     " __LL "%0, %1          # test_and_set_bit      \n"
-               "       or      %2, %0, %3                              \n"
-               "       " __SC  "%2, %1                                 \n"
-               "       beqz    %2, 2f                                  \n"
-               "        and    %2, %0, %3                              \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "        nop                                            \n"
-               "       .previous                                       \n"
-               "       .set    pop                                     \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "r" (1UL << bit), "m" (*m)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       " __LL "%0, %1  # test_and_set_bit      \n"
+                       "       or      %2, %0, %3                      \n"
+                       "       " __SC  "%2, %1                         \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "+m" (*m), "=&r" (res)
+                       : "r" (1UL << bit)
+                       : "memory");
+               } while (unlikely(!res));
+
+               res = temp & (1UL << bit);
        } else {
                volatile unsigned long *a = addr;
                unsigned long mask;
@@ -340,30 +326,26 @@ static inline int test_and_set_bit_lock(unsigned long nr,
                "       beqzl   %2, 1b                                  \n"
                "       and     %2, %0, %3                              \n"
                "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "r" (1UL << bit), "m" (*m)
+               : "=&r" (temp), "+m" (*m), "=&r" (res)
+               : "r" (1UL << bit)
                : "memory");
        } else if (kernel_uses_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
-               __asm__ __volatile__(
-               "       .set    push                                    \n"
-               "       .set    noreorder                               \n"
-               "       .set    mips3                                   \n"
-               "1:     " __LL "%0, %1          # test_and_set_bit      \n"
-               "       or      %2, %0, %3                              \n"
-               "       " __SC  "%2, %1                                 \n"
-               "       beqz    %2, 2f                                  \n"
-               "        and    %2, %0, %3                              \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "        nop                                            \n"
-               "       .previous                                       \n"
-               "       .set    pop                                     \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "r" (1UL << bit), "m" (*m)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       " __LL "%0, %1  # test_and_set_bit      \n"
+                       "       or      %2, %0, %3                      \n"
+                       "       " __SC  "%2, %1                         \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "+m" (*m), "=&r" (res)
+                       : "r" (1UL << bit)
+                       : "memory");
+               } while (unlikely(!res));
+
+               res = temp & (1UL << bit);
        } else {
                volatile unsigned long *a = addr;
                unsigned long mask;
@@ -410,49 +392,43 @@ static inline int test_and_clear_bit(unsigned long nr,
                "       beqzl   %2, 1b                                  \n"
                "       and     %2, %0, %3                              \n"
                "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "r" (1UL << bit), "m" (*m)
+               : "=&r" (temp), "+m" (*m), "=&r" (res)
+               : "r" (1UL << bit)
                : "memory");
 #ifdef CONFIG_CPU_MIPSR2
        } else if (kernel_uses_llsc && __builtin_constant_p(nr)) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
-               __asm__ __volatile__(
-               "1:     " __LL  "%0, %1         # test_and_clear_bit    \n"
-               "       " __EXT "%2, %0, %3, 1                          \n"
-               "       " __INS "%0, $0, %3, 1                          \n"
-               "       " __SC  "%0, %1                                 \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "ir" (bit), "m" (*m)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       " __LL  "%0, %1 # test_and_clear_bit    \n"
+                       "       " __EXT "%2, %0, %3, 1                  \n"
+                       "       " __INS "%0, $0, %3, 1                  \n"
+                       "       " __SC  "%0, %1                         \n"
+                       : "=&r" (temp), "+m" (*m), "=&r" (res)
+                       : "ir" (bit)
+                       : "memory");
+               } while (unlikely(!temp));
 #endif
        } else if (kernel_uses_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
-               __asm__ __volatile__(
-               "       .set    push                                    \n"
-               "       .set    noreorder                               \n"
-               "       .set    mips3                                   \n"
-               "1:     " __LL  "%0, %1         # test_and_clear_bit    \n"
-               "       or      %2, %0, %3                              \n"
-               "       xor     %2, %3                                  \n"
-               "       " __SC  "%2, %1                                 \n"
-               "       beqz    %2, 2f                                  \n"
-               "        and    %2, %0, %3                              \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "        nop                                            \n"
-               "       .previous                                       \n"
-               "       .set    pop                                     \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "r" (1UL << bit), "m" (*m)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       " __LL  "%0, %1 # test_and_clear_bit    \n"
+                       "       or      %2, %0, %3                      \n"
+                       "       xor     %2, %3                          \n"
+                       "       " __SC  "%2, %1                         \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "+m" (*m), "=&r" (res)
+                       : "r" (1UL << bit)
+                       : "memory");
+               } while (unlikely(!res));
+
+               res = temp & (1UL << bit);
        } else {
                volatile unsigned long *a = addr;
                unsigned long mask;
@@ -499,30 +475,26 @@ static inline int test_and_change_bit(unsigned long nr,
                "       beqzl   %2, 1b                                  \n"
                "       and     %2, %0, %3                              \n"
                "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "r" (1UL << bit), "m" (*m)
+               : "=&r" (temp), "+m" (*m), "=&r" (res)
+               : "r" (1UL << bit)
                : "memory");
        } else if (kernel_uses_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
-               __asm__ __volatile__(
-               "       .set    push                                    \n"
-               "       .set    noreorder                               \n"
-               "       .set    mips3                                   \n"
-               "1:     " __LL  "%0, %1         # test_and_change_bit   \n"
-               "       xor     %2, %0, %3                              \n"
-               "       " __SC  "\t%2, %1                               \n"
-               "       beqz    %2, 2f                                  \n"
-               "        and    %2, %0, %3                              \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "        nop                                            \n"
-               "       .previous                                       \n"
-               "       .set    pop                                     \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "r" (1UL << bit), "m" (*m)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       " __LL  "%0, %1 # test_and_change_bit   \n"
+                       "       xor     %2, %0, %3                      \n"
+                       "       " __SC  "\t%2, %1                       \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "+m" (*m), "=&r" (res)
+                       : "r" (1UL << bit)
+                       : "memory");
+               } while (unlikely(!res));
+
+               res = temp & (1UL << bit);
        } else {
                volatile unsigned long *a = addr;
                unsigned long mask;
index 15a8ef0707c695538fa5463d1ac05893e91f55b4..35cd1bab69c3c23d81015da791d2e7609526d962 100644 (file)
@@ -125,4 +125,16 @@ extern unsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3;
  */
 extern void plat_mem_setup(void);
 
+#ifdef CONFIG_SWIOTLB
+/*
+ * Optional platform hook to call swiotlb_setup().
+ */
+extern void plat_swiotlb_setup(void);
+
+#else
+
+static inline void plat_swiotlb_setup(void) {}
+
+#endif /* CONFIG_SWIOTLB */
+
 #endif /* _ASM_BOOTINFO_H */
index 2d28017e95d0756d1c1117847a5ff4811dffcea1..d8d1c2805ac71c7c67b4e1043d15e4e072845f78 100644 (file)
                "       move    $1, %z4                         \n"     \
                "       .set    mips3                           \n"     \
                "       " st "  $1, %1                          \n"     \
-               "       beqz    $1, 3f                          \n"     \
-               "2:                                             \n"     \
-               "       .subsection 2                           \n"     \
-               "3:     b       1b                              \n"     \
-               "       .previous                               \n"     \
+               "       beqz    $1, 1b                          \n"     \
                "       .set    pop                             \n"     \
+               "2:                                             \n"     \
                : "=&r" (__ret), "=R" (*m)                              \
                : "R" (*m), "Jr" (old), "Jr" (new)                      \
                : "memory");                                            \
index b201a8f5b127898ff645cfe0da800158a3b6595d..06d59dcbe24310a92669983231a51e3aad34d324 100644 (file)
  * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM
  */
 
-#define PRID_IMP_BCM4710       0x4000
-#define PRID_IMP_BCM3302       0x9000
-#define PRID_IMP_BCM6338       0x9000
-#define PRID_IMP_BCM6345       0x8000
-#define PRID_IMP_BCM6348       0x9100
-#define PRID_IMP_BCM4350       0xA000
-#define PRID_REV_BCM6358       0x0010
-#define PRID_REV_BCM6368       0x0030
+#define PRID_IMP_BMIPS4KC      0x4000
+#define PRID_IMP_BMIPS32       0x8000
+#define PRID_IMP_BMIPS3300     0x9000
+#define PRID_IMP_BMIPS3300_ALT 0x9100
+#define PRID_IMP_BMIPS3300_BUG 0x0000
+#define PRID_IMP_BMIPS43XX     0xa000
+#define PRID_IMP_BMIPS5000     0x5a00
+
+#define PRID_REV_BMIPS4380_LO  0x0040
+#define PRID_REV_BMIPS4380_HI  0x006f
 
 /*
  * These are the PRID's for when 23:16 == PRID_COMP_CAVIUM
 #define PRID_IMP_CAVIUM_CN56XX 0x0400
 #define PRID_IMP_CAVIUM_CN50XX 0x0600
 #define PRID_IMP_CAVIUM_CN52XX 0x0700
+#define PRID_IMP_CAVIUM_CN63XX 0x9000
 
 /*
  * These are the PRID's for when 23:16 == PRID_COMP_INGENIC
@@ -223,15 +226,14 @@ enum cpu_type_enum {
         * MIPS32 class processors
         */
        CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
-       CPU_ALCHEMY, CPU_PR4450, CPU_BCM3302, CPU_BCM4710,
-       CPU_BCM6338, CPU_BCM6345, CPU_BCM6348, CPU_BCM6358,
-       CPU_JZRISC,
+       CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,
+       CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC,
 
        /*
         * MIPS64 class processors
         */
        CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,
-       CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS,
+       CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS, CPU_CAVIUM_OCTEON2,
 
        CPU_LAST
 };
index 06746c5e80993d45b234cc047b22de19f6b7ffe4..c94fafba9e62fe238c5554e6910fb08820e83ed3 100644 (file)
@@ -3,4 +3,17 @@
  *
  * This file is released under the GPLv2
  */
-#include <asm-generic/device.h>
+#ifndef _ASM_MIPS_DEVICE_H
+#define _ASM_MIPS_DEVICE_H
+
+struct dma_map_ops;
+
+struct dev_archdata {
+       /* DMA operations on that device */
+       struct dma_map_ops *dma_ops;
+};
+
+struct pdev_archdata {
+};
+
+#endif /* _ASM_MIPS_DEVICE_H*/
index 18fbf7af8e93c2fa182b4906a66dfa25c3e17d00..655f849bd08d8767e81f6846ce205ce40e487980 100644 (file)
@@ -5,51 +5,41 @@
 #include <asm/cache.h>
 #include <asm-generic/dma-coherent.h>
 
-void *dma_alloc_noncoherent(struct device *dev, size_t size,
-                          dma_addr_t *dma_handle, gfp_t flag);
+#include <dma-coherence.h>
 
-void dma_free_noncoherent(struct device *dev, size_t size,
-                        void *vaddr, dma_addr_t dma_handle);
+extern struct dma_map_ops *mips_dma_map_ops;
 
-void *dma_alloc_coherent(struct device *dev, size_t size,
-                          dma_addr_t *dma_handle, gfp_t flag);
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+       if (dev && dev->archdata.dma_ops)
+               return dev->archdata.dma_ops;
+       else
+               return mips_dma_map_ops;
+}
 
-void dma_free_coherent(struct device *dev, size_t size,
-                        void *vaddr, dma_addr_t dma_handle);
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+       if (!dev->dma_mask)
+               return 0;
 
-extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
-       enum dma_data_direction direction);
-extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
-       size_t size, enum dma_data_direction direction);
-extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-       enum dma_data_direction direction);
-extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
-       unsigned long offset, size_t size, enum dma_data_direction direction);
-
-static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
-       size_t size, enum dma_data_direction direction)
+       return addr + size <= *dev->dma_mask;
+}
+
+static inline void dma_mark_clean(void *addr, size_t size) {}
+
+#include <asm-generic/dma-mapping-common.h>
+
+static inline int dma_supported(struct device *dev, u64 mask)
 {
-       dma_unmap_single(dev, dma_address, size, direction);
+       struct dma_map_ops *ops = get_dma_ops(dev);
+       return ops->dma_supported(dev, mask);
 }
 
-extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
-       int nhwentries, enum dma_data_direction direction);
-extern void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
-       size_t size, enum dma_data_direction direction);
-extern void dma_sync_single_for_device(struct device *dev,
-       dma_addr_t dma_handle, size_t size, enum dma_data_direction direction);
-extern void dma_sync_single_range_for_cpu(struct device *dev,
-       dma_addr_t dma_handle, unsigned long offset, size_t size,
-       enum dma_data_direction direction);
-extern void dma_sync_single_range_for_device(struct device *dev,
-       dma_addr_t dma_handle, unsigned long offset, size_t size,
-       enum dma_data_direction direction);
-extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
-       int nelems, enum dma_data_direction direction);
-extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
-       int nelems, enum dma_data_direction direction);
-extern int dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
-extern int dma_supported(struct device *dev, u64 mask);
+static inline int dma_mapping_error(struct device *dev, u64 mask)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+       return ops->mapping_error(dev, mask);
+}
 
 static inline int
 dma_set_mask(struct device *dev, u64 mask)
@@ -65,4 +55,34 @@ dma_set_mask(struct device *dev, u64 mask)
 extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
               enum dma_data_direction direction);
 
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+                                      dma_addr_t *dma_handle, gfp_t gfp)
+{
+       void *ret;
+       struct dma_map_ops *ops = get_dma_ops(dev);
+
+       ret = ops->alloc_coherent(dev, size, dma_handle, gfp);
+
+       debug_dma_alloc_coherent(dev, size, *dma_handle, ret);
+
+       return ret;
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+                                    void *vaddr, dma_addr_t dma_handle)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+
+       ops->free_coherent(dev, size, vaddr, dma_handle);
+
+       debug_dma_free_coherent(dev, size, vaddr, dma_handle);
+}
+
+
+void *dma_alloc_noncoherent(struct device *dev, size_t size,
+                          dma_addr_t *dma_handle, gfp_t flag);
+
+void dma_free_noncoherent(struct device *dev, size_t size,
+                        void *vaddr, dma_addr_t dma_handle);
+
 #endif /* _ASM_DMA_MAPPING_H */
index 1353c81065d1808d252d97b339fe34a052cca480..2d47da62d5a7d25dec4c4361c15e2170770158ee 100644 (file)
 #define MAX_DMA_ADDRESS                (PAGE_OFFSET + 0x01000000)
 #endif
 #define MAX_DMA_PFN            PFN_DOWN(virt_to_phys((void *)MAX_DMA_ADDRESS))
+
+#ifndef MAX_DMA32_PFN
 #define MAX_DMA32_PFN          (1UL << (32 - PAGE_SHIFT))
+#endif
 
 /* 8237 DMA controllers */
 #define IO_DMA1_BASE   0x00    /* 8 bit slave DMA, channels 0..3 */
index bdcdef02d147c6e014d86eb6748c7cd7c0628c9e..fffc8307a80a31e11424cc0996ec749ad5f1a0c4 100644 (file)
@@ -117,7 +117,7 @@ static __inline__ long local_sub_return(long i, local_t * l)
 
 #define local_cmpxchg(l, o, n) \
        ((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
-#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n)))
+#define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
 
 /**
  * local_add_unless - add unless the number is a given value
index 483ffea9ecb1de05bd6bcfacae3ce850d29c9b71..7919d76186bf1b78dca75c62e1fc41f731fc6ebb 100644 (file)
@@ -39,6 +39,7 @@
 #define AR7_REGS_UART0 (AR7_REGS_BASE + 0x0e00)
 #define AR7_REGS_USB   (AR7_REGS_BASE + 0x1200)
 #define AR7_REGS_RESET (AR7_REGS_BASE + 0x1600)
+#define AR7_REGS_PINSEL (AR7_REGS_BASE + 0x160C)
 #define AR7_REGS_VLYNQ0        (AR7_REGS_BASE + 0x1800)
 #define AR7_REGS_DCL   (AR7_REGS_BASE + 0x1a00)
 #define AR7_REGS_VLYNQ1        (AR7_REGS_BASE + 0x1c00)
 #define UR8_REGS_WDT   (AR7_REGS_BASE + 0x0b00)
 #define UR8_REGS_UART1 (AR7_REGS_BASE + 0x0f00)
 
+/* Titan registers */
+#define TITAN_REGS_ESWITCH_BASE        (0x08640000)
+#define TITAN_REGS_MAC0                (TITAN_REGS_ESWITCH_BASE)
+#define TITAN_REGS_MAC1                (TITAN_REGS_ESWITCH_BASE + 0x0800)
+#define TITAN_REGS_MDIO                (TITAN_REGS_ESWITCH_BASE + 0x02000)
+#define TITAN_REGS_VLYNQ0      (AR7_REGS_BASE + 0x1c00)
+#define TITAN_REGS_VLYNQ1      (AR7_REGS_BASE + 0x1300)
+
 #define AR7_RESET_PERIPHERAL   0x0
 #define AR7_RESET_SOFTWARE     0x4
 #define AR7_RESET_STATUS       0x8
 #define AR7_RESET_BIT_MDIO     22
 #define AR7_RESET_BIT_EPHY     26
 
+#define TITAN_RESET_BIT_EPHY1  28
+
 /* GPIO control registers */
 #define AR7_GPIO_INPUT 0x0
 #define AR7_GPIO_OUTPUT        0x4
 #define AR7_GPIO_DIR   0x8
 #define AR7_GPIO_ENABLE        0xc
+#define TITAN_GPIO_INPUT_0     0x0
+#define TITAN_GPIO_INPUT_1     0x4
+#define TITAN_GPIO_OUTPUT_0    0x8
+#define TITAN_GPIO_OUTPUT_1    0xc
+#define TITAN_GPIO_DIR_0       0x10
+#define TITAN_GPIO_DIR_1       0x14
+#define TITAN_GPIO_ENBL_0      0x18
+#define TITAN_GPIO_ENBL_1      0x1c
 
 #define AR7_CHIP_7100  0x18
 #define AR7_CHIP_7200  0x2b
 #define AR7_CHIP_7300  0x05
+#define AR7_CHIP_TITAN 0x07
+#define TITAN_CHIP_1050        0x0f
+#define TITAN_CHIP_1055        0x0e
+#define TITAN_CHIP_1056        0x0d
+#define TITAN_CHIP_1060        0x07
 
 /* Interrupts */
 #define AR7_IRQ_UART0  15
@@ -95,14 +119,29 @@ struct plat_dsl_data {
 
 extern int ar7_cpu_clock, ar7_bus_clock, ar7_dsp_clock;
 
+static inline int ar7_is_titan(void)
+{
+       return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x24)) & 0xffff) ==
+               AR7_CHIP_TITAN;
+}
+
 static inline u16 ar7_chip_id(void)
 {
-       return readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) & 0xffff;
+       return ar7_is_titan() ? AR7_CHIP_TITAN : (readl((void *)
+               KSEG1ADDR(AR7_REGS_GPIO + 0x14)) & 0xffff);
+}
+
+static inline u16 titan_chip_id(void)
+{
+       unsigned int val = readl((void *)KSEG1ADDR(AR7_REGS_GPIO +
+                                               TITAN_GPIO_INPUT_1));
+       return ((val >> 12) & 0x0f);
 }
 
 static inline u8 ar7_chip_rev(void)
 {
-       return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) >> 16) & 0xff;
+       return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + (ar7_is_titan() ? 0x24 :
+               0x14))) >> 16) & 0xff;
 }
 
 struct clk {
@@ -161,4 +200,8 @@ static inline void ar7_device_off(u32 bit)
        msleep(20);
 }
 
+int __init ar7_gpio_init(void);
+
+int __init ar7_gpio_init(void);
+
 #endif /* __AR7_H__ */
index abc317c0372eb183b4e2782705a4ea4eba11a6b2..c177cd1eed2588671d34d5a8d6fd74fb7123cfe4 100644 (file)
@@ -22,7 +22,8 @@
 #include <asm/mach-ar7/ar7.h>
 
 #define AR7_GPIO_MAX 32
-#define NR_BUILTIN_GPIO AR7_GPIO_MAX
+#define TITAN_GPIO_MAX 51
+#define NR_BUILTIN_GPIO TITAN_GPIO_MAX
 
 #define gpio_to_irq(gpio)      -1
 
index b952fc7215e204463174d30608eff1e9a5bcba00..0d5a42b5f47abb4091d3257270b72f80ed1fe3ce 100644 (file)
@@ -59,7 +59,7 @@
 #define cpu_has_veic           0
 #define cpu_hwrena_impl_bits   0xc0000000
 
-#define kernel_uses_smartmips_rixi (cpu_data[0].cputype == CPU_CAVIUM_OCTEON_PLUS)
+#define kernel_uses_smartmips_rixi (cpu_data[0].cputype != CPU_CAVIUM_OCTEON)
 
 #define ARCH_HAS_IRQ_PER_CPU   1
 #define ARCH_HAS_SPINLOCK_PREFETCH 1
@@ -81,4 +81,10 @@ static inline int octeon_has_saa(void)
        return id >= 0x000d0300;
 }
 
+/*
+ * The last 256MB are reserved for device to device mappings and the
+ * BAR1 hole.
+ */
+#define MAX_DMA32_PFN (((1ULL << 32) - (1ULL << 28)) >> PAGE_SHIFT)
+
 #endif
index 17d579471ec408fc2ab302e89a15953eac22f21f..be8fb4240cece35c234b14f43cd65a26b16a0988 100644 (file)
 
 struct device;
 
-dma_addr_t octeon_map_dma_mem(struct device *, void *, size_t);
-void octeon_unmap_dma_mem(struct device *, dma_addr_t);
+extern void octeon_pci_dma_init(void);
 
 static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
        size_t size)
 {
-       return octeon_map_dma_mem(dev, addr, size);
+       BUG();
 }
 
 static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
        struct page *page)
 {
-       return octeon_map_dma_mem(dev, page_address(page), PAGE_SIZE);
+       BUG();
 }
 
 static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
        dma_addr_t dma_addr)
 {
-       return dma_addr;
+       BUG();
 }
 
 static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
        size_t size, enum dma_data_direction direction)
 {
-       octeon_unmap_dma_mem(dev, dma_addr);
+       BUG();
 }
 
 static inline int plat_dma_supported(struct device *dev, u64 mask)
 {
-       return 1;
+       BUG();
 }
 
 static inline void plat_extra_sync_for_device(struct device *dev)
 {
-       mb();
+       BUG();
 }
 
 static inline int plat_device_is_coherent(struct device *dev)
@@ -60,7 +59,14 @@ static inline int plat_device_is_coherent(struct device *dev)
 static inline int plat_dma_mapping_error(struct device *dev,
                                         dma_addr_t dma_addr)
 {
-       return dma_addr == -1;
+       BUG();
 }
 
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
+
+struct dma_map_ops;
+extern struct dma_map_ops *octeon_pci_dma_map_ops;
+extern char *octeon_swiotlb;
+
 #endif /* __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H */
index d3d04018a8586945eead0fcc2da6a2e9e50ed1a6..016d0989b141355e9205c55a18be9b573e5875df 100644 (file)
@@ -26,14 +26,15 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
        return pa;
 }
 
-static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+       struct page *page)
 {
        dma_addr_t pa = dev_to_baddr(dev, page_to_phys(page));
 
        return pa;
 }
 
-static unsigned long plat_dma_addr_to_phys(struct device *dev,
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
        dma_addr_t dma_addr)
 {
        return dma_addr & ~(0xffUL << 56);
index 37855955b313310a3cdc4ef531b989d54388ff6b..c8fb5aacf50a412eb89e0397f5a55b73655ce8d3 100644 (file)
@@ -37,7 +37,8 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
        return pa;
 }
 
-static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+       struct page *page)
 {
        dma_addr_t pa;
 
@@ -50,7 +51,7 @@ static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
 }
 
 /* This is almost certainly wrong but it's what dma-ip32.c used to use  */
-static unsigned long plat_dma_addr_to_phys(struct device *dev,
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
        dma_addr_t dma_addr)
 {
        unsigned long addr = dma_addr & RAM_OFFSET_MASK;
index f93aee59454a041416ef5054a3efe9e647211037..302101b54acb1e72d47ec080b71f126d44b7c9c0 100644 (file)
 
 struct device;
 
-static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
 {
        return vdma_alloc(virt_to_phys(addr), size);
 }
 
-static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+       struct page *page)
 {
        return vdma_alloc(page_to_phys(page), PAGE_SIZE);
 }
 
-static unsigned long plat_dma_addr_to_phys(struct device *dev,
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
        dma_addr_t dma_addr)
 {
        return vdma_log2phys(dma_addr);
 }
 
-static void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
        size_t size, enum dma_data_direction direction)
 {
        vdma_free(dma_addr);
index 335474c155f6e6187aa19ce49527712ca954c8fb..4d9870975382be738893a92bcb2a68ca96fe3181 100644 (file)
@@ -1040,6 +1040,12 @@ do {                                                                     \
 #define read_c0_dtaglo()       __read_32bit_c0_register($28, 2)
 #define write_c0_dtaglo(val)   __write_32bit_c0_register($28, 2, val)
 
+#define read_c0_ddatalo()      __read_32bit_c0_register($28, 3)
+#define write_c0_ddatalo(val)  __write_32bit_c0_register($28, 3, val)
+
+#define read_c0_staglo()       __read_32bit_c0_register($28, 4)
+#define write_c0_staglo(val)   __write_32bit_c0_register($28, 4, val)
+
 #define read_c0_taghi()                __read_32bit_c0_register($29, 0)
 #define write_c0_taghi(val)    __write_32bit_c0_register($29, 0, val)
 
@@ -1082,6 +1088,51 @@ do {                                                                     \
 #define read_octeon_c0_dcacheerr()     __read_64bit_c0_register($27, 1)
 #define write_octeon_c0_dcacheerr(val) __write_64bit_c0_register($27, 1, val)
 
+/* BMIPS3300 */
+#define read_c0_brcm_config_0()                __read_32bit_c0_register($22, 0)
+#define write_c0_brcm_config_0(val)    __write_32bit_c0_register($22, 0, val)
+
+#define read_c0_brcm_bus_pll()         __read_32bit_c0_register($22, 4)
+#define write_c0_brcm_bus_pll(val)     __write_32bit_c0_register($22, 4, val)
+
+#define read_c0_brcm_reset()           __read_32bit_c0_register($22, 5)
+#define write_c0_brcm_reset(val)       __write_32bit_c0_register($22, 5, val)
+
+/* BMIPS4380 */
+#define read_c0_brcm_cmt_intr()                __read_32bit_c0_register($22, 1)
+#define write_c0_brcm_cmt_intr(val)    __write_32bit_c0_register($22, 1, val)
+
+#define read_c0_brcm_cmt_ctrl()                __read_32bit_c0_register($22, 2)
+#define write_c0_brcm_cmt_ctrl(val)    __write_32bit_c0_register($22, 2, val)
+
+#define read_c0_brcm_cmt_local()       __read_32bit_c0_register($22, 3)
+#define write_c0_brcm_cmt_local(val)   __write_32bit_c0_register($22, 3, val)
+
+#define read_c0_brcm_config_1()                __read_32bit_c0_register($22, 5)
+#define write_c0_brcm_config_1(val)    __write_32bit_c0_register($22, 5, val)
+
+#define read_c0_brcm_cbr()             __read_32bit_c0_register($22, 6)
+#define write_c0_brcm_cbr(val)         __write_32bit_c0_register($22, 6, val)
+
+/* BMIPS5000 */
+#define read_c0_brcm_config()          __read_32bit_c0_register($22, 0)
+#define write_c0_brcm_config(val)      __write_32bit_c0_register($22, 0, val)
+
+#define read_c0_brcm_mode()            __read_32bit_c0_register($22, 1)
+#define write_c0_brcm_mode(val)                __write_32bit_c0_register($22, 1, val)
+
+#define read_c0_brcm_action()          __read_32bit_c0_register($22, 2)
+#define write_c0_brcm_action(val)      __write_32bit_c0_register($22, 2, val)
+
+#define read_c0_brcm_edsp()            __read_32bit_c0_register($22, 3)
+#define write_c0_brcm_edsp(val)                __write_32bit_c0_register($22, 3, val)
+
+#define read_c0_brcm_bootvec()         __read_32bit_c0_register($22, 4)
+#define write_c0_brcm_bootvec(val)     __write_32bit_c0_register($22, 4, val)
+
+#define read_c0_brcm_sleepcount()      __read_32bit_c0_register($22, 7)
+#define write_c0_brcm_sleepcount(val)  __write_32bit_c0_register($22, 7, val)
+
 /*
  * Macros to access the floating point coprocessor control registers
  */
index ec94b9ab7be1f485b54bf03d1722fff5fb43d1f1..30d68f2365e0621624aefa12fdb910f88413ff6d 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
 #ifndef __CVMX_AGL_DEFS_H__
 #define __CVMX_AGL_DEFS_H__
 
-#define CVMX_AGL_GMX_BAD_REG \
-        CVMX_ADD_IO_SEG(0x00011800E0000518ull)
-#define CVMX_AGL_GMX_BIST \
-        CVMX_ADD_IO_SEG(0x00011800E0000400ull)
-#define CVMX_AGL_GMX_DRV_CTL \
-        CVMX_ADD_IO_SEG(0x00011800E00007F0ull)
-#define CVMX_AGL_GMX_INF_MODE \
-        CVMX_ADD_IO_SEG(0x00011800E00007F8ull)
-#define CVMX_AGL_GMX_PRTX_CFG(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000010ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM0(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000180ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM1(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000188ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM2(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000190ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM3(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000198ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM4(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00001A0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM5(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00001A8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM_EN(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000108ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CTL(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000100ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_DECISION(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000040ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_FRM_CHK(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000020ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_FRM_CTL(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000018ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_FRM_MAX(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000030ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_FRM_MIN(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000028ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_IFG(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000058ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_INT_EN(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000008ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_INT_REG(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000000ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_JABBER(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000038ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_PAUSE_DROP_TIME(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000068ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_CTL(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000050ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_OCTS(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000088ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_OCTS_CTL(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000098ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_OCTS_DMAC(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00000A8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_OCTS_DRP(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00000B8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_PKTS(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000080ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00000C0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_PKTS_CTL(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000090ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_PKTS_DMAC(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00000A0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00000B0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_UDD_SKP(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000048ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RX_BP_DROPX(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000420ull + (((offset) & 1) * 8))
-#define CVMX_AGL_GMX_RX_BP_OFFX(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000460ull + (((offset) & 1) * 8))
-#define CVMX_AGL_GMX_RX_BP_ONX(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000440ull + (((offset) & 1) * 8))
-#define CVMX_AGL_GMX_RX_PRT_INFO \
-        CVMX_ADD_IO_SEG(0x00011800E00004E8ull)
-#define CVMX_AGL_GMX_RX_TX_STATUS \
-        CVMX_ADD_IO_SEG(0x00011800E00007E8ull)
-#define CVMX_AGL_GMX_SMACX(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000230ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_STAT_BP \
-        CVMX_ADD_IO_SEG(0x00011800E0000520ull)
-#define CVMX_AGL_GMX_TXX_APPEND(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000218ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_CTL(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000270ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_MIN_PKT(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000240ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_PAUSE_PKT_INTERVAL(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000248ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_PAUSE_PKT_TIME(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000238ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_PAUSE_TOGO(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000258ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_PAUSE_ZERO(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000260ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_SOFT_PAUSE(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000250ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT0(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000280ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT1(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000288ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT2(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000290ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT3(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000298ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT4(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00002A0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT5(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00002A8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT6(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00002B0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT7(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00002B8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT8(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00002C0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT9(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00002C8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STATS_CTL(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000268ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_THRESH(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000210ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TX_BP \
-        CVMX_ADD_IO_SEG(0x00011800E00004D0ull)
-#define CVMX_AGL_GMX_TX_COL_ATTEMPT \
-        CVMX_ADD_IO_SEG(0x00011800E0000498ull)
-#define CVMX_AGL_GMX_TX_IFG \
-        CVMX_ADD_IO_SEG(0x00011800E0000488ull)
-#define CVMX_AGL_GMX_TX_INT_EN \
-        CVMX_ADD_IO_SEG(0x00011800E0000508ull)
-#define CVMX_AGL_GMX_TX_INT_REG&nbs