From 225921c2147575722fe1cade45ac57e741d20832 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 29 Oct 2010 00:56:46 -0400 Subject: [PATCH] --- yaml --- r: 220970 b: refs/heads/master c: 4908980b241bc639b71ef47b727b4bc7c0174afe h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/Documentation/DocBook/kgdb.tmpl | 13 +- trunk/Makefile | 3 - trunk/arch/arm/include/asm/kgdb.h | 5 +- trunk/arch/arm/kernel/kgdb.c | 2 +- trunk/arch/blackfin/kernel/kgdb.c | 3 +- trunk/arch/ia64/kernel/perfmon.c | 9 +- trunk/arch/mips/Kconfig | 79 - trunk/arch/mips/Kconfig.debug | 9 - trunk/arch/mips/Makefile | 4 +- trunk/arch/mips/ar7/gpio.c | 243 +- trunk/arch/mips/ar7/platform.c | 56 - trunk/arch/mips/ar7/prom.c | 2 - trunk/arch/mips/ar7/setup.c | 14 - trunk/arch/mips/bcm63xx/cpu.c | 30 +- trunk/arch/mips/cavium-octeon/Kconfig | 23 - trunk/arch/mips/cavium-octeon/csrc-octeon.c | 34 +- trunk/arch/mips/cavium-octeon/dma-octeon.c | 581 ++- .../mips/cavium-octeon/executive/cvmx-l2c.c | 810 ++-- .../arch/mips/cavium-octeon/octeon-platform.c | 112 +- trunk/arch/mips/cavium-octeon/serial.c | 2 +- trunk/arch/mips/cavium-octeon/setup.c | 120 +- trunk/arch/mips/include/asm/atomic.h | 208 +- trunk/arch/mips/include/asm/bitops.h | 270 +- trunk/arch/mips/include/asm/bootinfo.h | 12 - trunk/arch/mips/include/asm/cmpxchg.h | 7 +- trunk/arch/mips/include/asm/cpu.h | 26 +- trunk/arch/mips/include/asm/device.h | 15 +- trunk/arch/mips/include/asm/dma-mapping.h | 96 +- trunk/arch/mips/include/asm/dma.h | 3 - trunk/arch/mips/include/asm/local.h | 2 +- trunk/arch/mips/include/asm/mach-ar7/ar7.h | 47 +- trunk/arch/mips/include/asm/mach-ar7/gpio.h | 3 +- .../cpu-feature-overrides.h | 8 +- .../asm/mach-cavium-octeon/dma-coherence.h | 24 +- .../include/asm/mach-ip27/dma-coherence.h | 5 +- .../include/asm/mach-ip32/dma-coherence.h | 5 +- .../include/asm/mach-jazz/dma-coherence.h | 9 +- trunk/arch/mips/include/asm/mipsregs.h | 51 - .../mips/include/asm/octeon/cvmx-agl-defs.h | 616 +-- trunk/arch/mips/include/asm/octeon/cvmx-asm.h | 11 - .../mips/include/asm/octeon/cvmx-ciu-defs.h | 857 +--- .../mips/include/asm/octeon/cvmx-gpio-defs.h | 74 +- .../mips/include/asm/octeon/cvmx-iob-defs.h | 242 +- .../mips/include/asm/octeon/cvmx-ipd-defs.h | 314 +- .../mips/include/asm/octeon/cvmx-l2c-defs.h | 738 +-- trunk/arch/mips/include/asm/octeon/cvmx-l2c.h | 225 +- .../mips/include/asm/octeon/cvmx-l2d-defs.h | 38 +- .../mips/include/asm/octeon/cvmx-l2t-defs.h | 5 +- .../mips/include/asm/octeon/cvmx-led-defs.h | 41 +- .../mips/include/asm/octeon/cvmx-mio-defs.h | 807 +--- .../mips/include/asm/octeon/cvmx-mixx-defs.h | 200 +- .../mips/include/asm/octeon/cvmx-npei-defs.h | 681 +-- .../mips/include/asm/octeon/cvmx-npi-defs.h | 362 +- .../mips/include/asm/octeon/cvmx-pci-defs.h | 265 +- .../include/asm/octeon/cvmx-pciercx-defs.h | 435 +- .../mips/include/asm/octeon/cvmx-pescx-defs.h | 50 +- .../mips/include/asm/octeon/cvmx-pexp-defs.h | 378 +- .../mips/include/asm/octeon/cvmx-pow-defs.h | 157 +- .../mips/include/asm/octeon/cvmx-rnm-defs.h | 67 +- .../mips/include/asm/octeon/cvmx-smix-defs.h | 46 +- .../mips/include/asm/octeon/cvmx-uctlx-defs.h | 261 -- .../mips/include/asm/octeon/octeon-model.h | 36 +- trunk/arch/mips/include/asm/octeon/octeon.h | 1 - .../arch/mips/include/asm/octeon/pci-octeon.h | 10 - trunk/arch/mips/include/asm/perf_event.h | 25 - trunk/arch/mips/include/asm/pgtable-64.h | 4 +- trunk/arch/mips/include/asm/processor.h | 40 +- trunk/arch/mips/include/asm/system.h | 52 +- trunk/arch/mips/include/asm/thread_info.h | 2 - trunk/arch/mips/include/asm/uaccess.h | 4 +- trunk/arch/mips/kernel/Makefile | 2 - trunk/arch/mips/kernel/cpu-probe.c | 82 +- trunk/arch/mips/kernel/irq.c | 24 - trunk/arch/mips/kernel/perf_event.c | 601 --- trunk/arch/mips/kernel/perf_event_mipsxx.c | 1052 ----- trunk/arch/mips/kernel/setup.c | 1 - trunk/arch/mips/kernel/traps.c | 31 +- trunk/arch/mips/kernel/unaligned.c | 7 - trunk/arch/mips/loongson/Kconfig | 2 + trunk/arch/mips/math-emu/cp1emu.c | 3 - trunk/arch/mips/mm/c-octeon.c | 16 +- trunk/arch/mips/mm/c-r4k.c | 21 +- trunk/arch/mips/mm/dma-default.c | 165 +- trunk/arch/mips/mm/fault.c | 11 +- trunk/arch/mips/mm/sc-mips.c | 34 +- trunk/arch/mips/mm/tlbex.c | 11 +- trunk/arch/mips/mm/uasm.c | 20 +- trunk/arch/mips/pci/pci-octeon.c | 60 +- trunk/arch/mips/pci/pcie-octeon.c | 5 - trunk/arch/powerpc/include/asm/kgdb.h | 1 - trunk/arch/powerpc/kernel/kgdb.c | 188 +- .../arch/powerpc/platforms/cell/spufs/inode.c | 10 +- trunk/arch/s390/Kconfig | 61 +- trunk/arch/s390/hypfs/hypfs_diag.c | 19 +- trunk/arch/s390/hypfs/inode.c | 8 +- trunk/arch/s390/include/asm/dasd.h | 40 +- trunk/arch/s390/kernel/asm-offsets.c | 6 +- trunk/arch/s390/kernel/early.c | 2 + trunk/arch/s390/kernel/entry.S | 1 - trunk/arch/s390/kernel/entry64.S | 1 - trunk/arch/s390/kernel/kprobes.c | 9 +- trunk/arch/s390/kernel/setup.c | 3 - trunk/arch/s390/kernel/sysinfo.c | 2 - trunk/arch/s390/kernel/topology.c | 6 +- trunk/arch/s390/kernel/vdso32/clock_getres.S | 6 +- trunk/arch/s390/kernel/vdso32/clock_gettime.S | 4 +- trunk/arch/s390/kernel/vdso64/clock_getres.S | 6 +- trunk/arch/s390/kernel/vdso64/clock_gettime.S | 4 +- trunk/arch/sparc/Kconfig | 3 + trunk/arch/sparc/include/asm/jump_label.h | 1 + trunk/arch/sparc/kernel/irq_32.c | 4 +- trunk/arch/sparc/kernel/leon_smp.c | 4 +- trunk/arch/sparc/kernel/rtrap_32.S | 6 +- trunk/arch/sparc/kernel/rtrap_64.S | 36 +- trunk/arch/sparc/mm/fault_32.c | 12 - trunk/arch/x86/kernel/kgdb.c | 3 +- trunk/drivers/ata/pata_octeon_cf.c | 2 +- trunk/drivers/base/devtmpfs.c | 18 +- trunk/drivers/char/agp/parisc-agp.c | 1 - trunk/drivers/dma/Kconfig | 4 +- trunk/drivers/ide/hpt366.c | 14 +- trunk/drivers/ide/ide-dma.c | 11 +- trunk/drivers/infiniband/hw/ipath/ipath_fs.c | 14 +- trunk/drivers/infiniband/hw/qib/qib_fs.c | 14 +- trunk/drivers/isdn/capi/capifs.c | 8 +- trunk/drivers/md/bitmap.c | 30 +- trunk/drivers/md/bitmap.h | 4 +- trunk/drivers/md/faulty.c | 2 +- trunk/drivers/md/md.c | 162 +- trunk/drivers/md/md.h | 8 +- trunk/drivers/md/raid1.c | 224 +- trunk/drivers/md/raid1.h | 2 + trunk/drivers/md/raid10.c | 42 +- trunk/drivers/md/raid5.c | 6 +- trunk/drivers/misc/ibmasm/ibmasmfs.c | 9 +- trunk/drivers/misc/kgdbts.c | 16 +- trunk/drivers/mtd/mtdchar.c | 10 +- trunk/drivers/mtd/mtdsuper.c | 54 +- trunk/drivers/net/Kconfig | 1 - trunk/drivers/net/atarilance.c | 2 +- trunk/drivers/net/cxgb3/cxgb3_main.c | 2 +- trunk/drivers/net/cxgb3/sge.c | 4 +- trunk/drivers/net/e1000e/82571.c | 38 - trunk/drivers/net/e1000e/e1000.h | 3 - trunk/drivers/net/e1000e/netdev.c | 29 +- trunk/drivers/net/igb/igb_main.c | 1 + trunk/drivers/net/igbvf/netdev.c | 8 +- trunk/drivers/net/ixgb/ixgb_main.c | 1 - trunk/drivers/net/ixgbe/ixgbe_dcb.c | 39 +- trunk/drivers/net/ixgbe/ixgbe_dcb.h | 5 +- trunk/drivers/net/ixgbe/ixgbe_dcb_82599.c | 5 - trunk/drivers/net/ixgbe/ixgbe_dcb_82599.h | 3 - trunk/drivers/net/ixgbe/ixgbe_main.c | 12 +- trunk/drivers/net/lib8390.c | 1 + trunk/drivers/net/netxen/netxen_nic_ctx.c | 15 + trunk/drivers/net/netxen/netxen_nic_main.c | 7 - trunk/drivers/net/stmmac/stmmac_main.c | 40 +- trunk/drivers/net/wireless/ath/ath5k/attach.c | 17 +- trunk/drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- .../drivers/net/wireless/ath/ath9k/hif_usb.c | 10 +- trunk/drivers/net/wireless/ath/ath9k/main.c | 31 +- trunk/drivers/net/wireless/ath/ath9k/rc.c | 2 +- trunk/drivers/net/wireless/ath/ath9k/recv.c | 15 +- trunk/drivers/net/wireless/ath/ath9k/xmit.c | 18 +- trunk/drivers/net/wireless/b43/sdio.c | 2 - trunk/drivers/net/wireless/libertas/if_sdio.c | 32 +- trunk/drivers/oprofile/oprofilefs.c | 8 +- trunk/drivers/s390/block/dasd_eckd.c | 69 - trunk/drivers/s390/block/dasd_eckd.h | 1 - trunk/drivers/s390/char/tape_core.c | 9 +- trunk/drivers/s390/char/tape_std.c | 4 +- trunk/drivers/staging/Kconfig | 2 + trunk/drivers/staging/Makefile | 1 + trunk/drivers/staging/autofs/init.c | 8 +- trunk/drivers/staging/dream/Kconfig | 13 + trunk/drivers/staging/dream/Makefile | 5 + trunk/drivers/staging/dream/TODO | 13 + trunk/drivers/staging/dream/camera/Kconfig | 46 + trunk/drivers/staging/dream/camera/Makefile | 8 + .../drivers/staging/dream/camera/msm_camera.c | 2181 +++++++++ trunk/drivers/staging/dream/camera/msm_io7x.c | 291 ++ trunk/drivers/staging/dream/camera/msm_io8x.c | 320 ++ trunk/drivers/staging/dream/camera/msm_v4l2.c | 798 ++++ .../drivers/staging/dream/camera/msm_vfe7x.c | 702 +++ .../drivers/staging/dream/camera/msm_vfe7x.h | 255 ++ .../drivers/staging/dream/camera/msm_vfe8x.c | 736 +++ .../drivers/staging/dream/camera/msm_vfe8x.h | 895 ++++ .../staging/dream/camera/msm_vfe8x_proc.c | 4003 +++++++++++++++++ .../staging/dream/camera/msm_vfe8x_proc.h | 1549 +++++++ trunk/drivers/staging/dream/camera/mt9d112.c | 762 ++++ trunk/drivers/staging/dream/camera/mt9d112.h | 36 + .../staging/dream/camera/mt9d112_reg.c | 307 ++ trunk/drivers/staging/dream/camera/mt9p012.h | 51 + .../staging/dream/camera/mt9p012_fox.c | 1306 ++++++ .../staging/dream/camera/mt9p012_reg.c | 573 +++ trunk/drivers/staging/dream/camera/mt9t013.c | 1497 ++++++ trunk/drivers/staging/dream/camera/mt9t013.h | 48 + .../staging/dream/camera/mt9t013_reg.c | 266 ++ trunk/drivers/staging/dream/camera/s5k3e2fx.c | 1307 ++++++ trunk/drivers/staging/dream/camera/s5k3e2fx.h | 9 + trunk/drivers/staging/dream/generic_gpio.c | 274 ++ trunk/drivers/staging/dream/gpio_axis.c | 181 + trunk/drivers/staging/dream/gpio_event.c | 224 + trunk/drivers/staging/dream/gpio_input.c | 337 ++ trunk/drivers/staging/dream/gpio_matrix.c | 399 ++ trunk/drivers/staging/dream/gpio_output.c | 84 + .../dream/include/linux/android_pmem.h | 80 + .../staging/dream/include/linux/gpio_event.h | 154 + .../staging/dream/include/linux/msm_adsp.h | 84 + .../staging/dream/include/linux/msm_audio.h | 115 + .../dream/include/linux/msm_rpcrouter.h | 47 + .../staging/dream/include/linux/wakelock.h | 91 + .../staging/dream/include/mach/camera.h | 279 ++ .../staging/dream/include/mach/msm_adsp.h | 112 + .../dream/include/mach/msm_rpcrouter.h | 179 + .../staging/dream/include/mach/msm_smd.h | 107 + .../include/mach/qdsp5/qdsp5audplaycmdi.h | 94 + .../include/mach/qdsp5/qdsp5audplaymsg.h | 70 + .../dream/include/mach/qdsp5/qdsp5audppcmdi.h | 914 ++++ .../dream/include/mach/qdsp5/qdsp5audppmsg.h | 318 ++ .../include/mach/qdsp5/qdsp5audpreproccmdi.h | 256 ++ .../include/mach/qdsp5/qdsp5audpreprocmsg.h | 85 + .../include/mach/qdsp5/qdsp5audreccmdi.h | 176 + .../dream/include/mach/qdsp5/qdsp5audrecmsg.h | 127 + .../dream/include/mach/qdsp5/qdsp5jpegcmdi.h | 376 ++ .../dream/include/mach/qdsp5/qdsp5jpegmsg.h | 177 + .../dream/include/mach/qdsp5/qdsp5lpmcmdi.h | 82 + .../dream/include/mach/qdsp5/qdsp5lpmmsg.h | 80 + .../dream/include/mach/qdsp5/qdsp5vdeccmdi.h | 235 + .../dream/include/mach/qdsp5/qdsp5vdecmsg.h | 107 + .../dream/include/mach/qdsp5/qdsp5venccmdi.h | 212 + .../dream/include/mach/qdsp5/qdsp5vfecmdi.h | 910 ++++ .../dream/include/mach/qdsp5/qdsp5vfemsg.h | 290 ++ .../staging/dream/include/media/msm_camera.h | 388 ++ trunk/drivers/staging/dream/pmem.c | 1333 ++++++ trunk/drivers/staging/dream/qdsp5/Makefile | 18 + trunk/drivers/staging/dream/qdsp5/adsp.c | 1159 +++++ trunk/drivers/staging/dream/qdsp5/adsp.h | 369 ++ trunk/drivers/staging/dream/qdsp5/adsp_6210.c | 283 ++ trunk/drivers/staging/dream/qdsp5/adsp_6220.c | 284 ++ trunk/drivers/staging/dream/qdsp5/adsp_6225.c | 328 ++ .../drivers/staging/dream/qdsp5/adsp_driver.c | 643 +++ trunk/drivers/staging/dream/qdsp5/adsp_info.c | 121 + .../dream/qdsp5/adsp_jpeg_patch_event.c | 31 + .../dream/qdsp5/adsp_jpeg_verify_cmd.c | 182 + .../staging/dream/qdsp5/adsp_lpm_verify_cmd.c | 65 + .../dream/qdsp5/adsp_vfe_patch_event.c | 54 + .../staging/dream/qdsp5/adsp_vfe_verify_cmd.c | 239 + .../dream/qdsp5/adsp_video_verify_cmd.c | 163 + .../dream/qdsp5/adsp_videoenc_verify_cmd.c | 235 + trunk/drivers/staging/dream/qdsp5/audio_aac.c | 1054 +++++ .../drivers/staging/dream/qdsp5/audio_amrnb.c | 875 ++++ .../drivers/staging/dream/qdsp5/audio_evrc.c | 847 ++++ trunk/drivers/staging/dream/qdsp5/audio_in.c | 970 ++++ trunk/drivers/staging/dream/qdsp5/audio_mp3.c | 972 ++++ trunk/drivers/staging/dream/qdsp5/audio_out.c | 841 ++++ .../drivers/staging/dream/qdsp5/audio_qcelp.c | 858 ++++ trunk/drivers/staging/dream/qdsp5/audmgr.c | 314 ++ trunk/drivers/staging/dream/qdsp5/audmgr.h | 215 + .../drivers/staging/dream/qdsp5/audmgr_new.h | 213 + trunk/drivers/staging/dream/qdsp5/audpp.c | 429 ++ trunk/drivers/staging/dream/qdsp5/evlog.h | 134 + trunk/drivers/staging/dream/qdsp5/snd.c | 280 ++ .../drivers/staging/dream/synaptics_i2c_rmi.c | 649 +++ .../drivers/staging/dream/synaptics_i2c_rmi.h | 53 + trunk/drivers/staging/pohmelfs/inode.c | 9 +- trunk/drivers/staging/smbfs/inode.c | 8 +- trunk/drivers/usb/core/inode.c | 8 +- trunk/drivers/usb/gadget/f_fs.c | 14 +- trunk/drivers/usb/gadget/inode.c | 10 +- trunk/drivers/usb/gadget/u_ether.c | 2 +- trunk/drivers/usb/host/Kconfig | 30 +- trunk/drivers/usb/host/Makefile | 1 - trunk/drivers/usb/host/ehci-hcd.c | 5 - trunk/drivers/usb/host/ehci-octeon.c | 207 - trunk/drivers/usb/host/octeon2-common.c | 185 - trunk/drivers/usb/host/ohci-hcd.c | 5 - trunk/drivers/usb/host/ohci-octeon.c | 214 - trunk/drivers/watchdog/octeon-wdt-main.c | 4 +- trunk/drivers/xen/xenfs/super.c | 8 +- trunk/fs/9p/vfs_super.c | 22 +- trunk/fs/adfs/super.c | 9 +- trunk/fs/affs/super.c | 9 +- trunk/fs/afs/super.c | 19 +- trunk/fs/anon_inodes.c | 10 +- trunk/fs/autofs4/init.c | 8 +- trunk/fs/befs/linuxvfs.c | 11 +- trunk/fs/bfs/inode.c | 8 +- trunk/fs/binfmt_misc.c | 8 +- trunk/fs/block_dev.c | 8 +- trunk/fs/btrfs/super.c | 15 +- trunk/fs/ceph/super.c | 50 +- trunk/fs/cifs/Kconfig | 3 - trunk/fs/cifs/cifsencrypt.c | 427 +- trunk/fs/cifs/cifsfs.c | 16 +- trunk/fs/cifs/cifsfs.h | 2 +- trunk/fs/cifs/cifsglob.h | 55 +- trunk/fs/cifs/cifspdu.h | 13 +- trunk/fs/cifs/cifsproto.h | 14 +- trunk/fs/cifs/cifssmb.c | 4 +- trunk/fs/cifs/connect.c | 51 +- trunk/fs/cifs/file.c | 57 +- trunk/fs/cifs/inode.c | 15 +- trunk/fs/cifs/misc.c | 2 +- trunk/fs/cifs/sess.c | 166 +- trunk/fs/cifs/transport.c | 6 +- trunk/fs/coda/inode.c | 8 +- trunk/fs/compat.c | 12 +- trunk/fs/configfs/mount.c | 8 +- trunk/fs/cramfs/inode.c | 9 +- trunk/fs/debugfs/inode.c | 8 +- trunk/fs/devpts/inode.c | 32 +- trunk/fs/ecryptfs/ecryptfs_kernel.h | 1 - trunk/fs/ecryptfs/inode.c | 11 +- trunk/fs/ecryptfs/keystore.c | 45 +- trunk/fs/ecryptfs/main.c | 20 +- trunk/fs/ecryptfs/super.c | 2 - trunk/fs/efs/super.c | 8 +- trunk/fs/exofs/super.c | 10 +- trunk/fs/ext2/super.c | 8 +- trunk/fs/ext3/super.c | 8 +- trunk/fs/ext4/super.c | 16 +- trunk/fs/fat/namei_msdos.c | 9 +- trunk/fs/fat/namei_vfat.c | 9 +- trunk/fs/freevxfs/vxfs_super.c | 9 +- trunk/fs/fuse/control.c | 10 +- trunk/fs/fuse/inode.c | 17 +- trunk/fs/gfs2/ops_fstype.c | 51 +- trunk/fs/hfs/super.c | 9 +- trunk/fs/hfsplus/super.c | 10 +- trunk/fs/hostfs/hostfs_kern.c | 8 +- trunk/fs/hpfs/super.c | 9 +- trunk/fs/hppfs/hppfs.c | 8 +- trunk/fs/hugetlbfs/inode.c | 8 +- trunk/fs/internal.h | 2 +- trunk/fs/isofs/inode.c | 9 +- trunk/fs/jffs2/super.c | 9 +- trunk/fs/jfs/super.c | 9 +- trunk/fs/libfs.c | 14 +- trunk/fs/logfs/dev_bdev.c | 15 +- trunk/fs/logfs/dev_mtd.c | 18 +- trunk/fs/logfs/logfs.h | 22 +- trunk/fs/logfs/super.c | 77 +- trunk/fs/minix/inode.c | 9 +- trunk/fs/namei.c | 2 - trunk/fs/ncpfs/inode.c | 8 +- trunk/fs/nfs/super.c | 96 +- trunk/fs/nfs/unlink.c | 4 +- trunk/fs/nfsd/nfsctl.c | 8 +- trunk/fs/nilfs2/super.c | 16 +- trunk/fs/ntfs/super.c | 9 +- trunk/fs/ocfs2/dlmfs/dlmfs.c | 8 +- trunk/fs/ocfs2/super.c | 11 +- trunk/fs/omfs/inode.c | 9 +- trunk/fs/open.c | 6 +- trunk/fs/openpromfs/inode.c | 8 +- trunk/fs/pipe.c | 9 +- trunk/fs/proc/root.c | 16 +- trunk/fs/qnx4/inode.c | 9 +- trunk/fs/ramfs/inode.c | 17 +- trunk/fs/read_write.c | 62 +- trunk/fs/reiserfs/super.c | 9 +- trunk/fs/romfs/super.c | 17 +- trunk/fs/squashfs/super.c | 10 +- trunk/fs/squashfs/xattr.c | 9 +- trunk/fs/squashfs/xattr.h | 4 +- trunk/fs/squashfs/xattr_id.c | 1 - trunk/fs/super.c | 111 +- trunk/fs/sysfs/mount.c | 32 +- trunk/fs/sysv/super.c | 17 +- trunk/fs/ubifs/super.c | 13 +- trunk/fs/udf/super.c | 9 +- trunk/fs/ufs/super.c | 8 +- trunk/fs/xfs/linux-2.6/xfs_super.c | 12 +- trunk/include/linux/dccp.h | 4 +- trunk/include/linux/fs.h | 22 +- trunk/include/linux/kgdb.h | 13 +- trunk/include/linux/mtd/super.h | 5 +- trunk/include/linux/ramfs.h | 4 +- trunk/include/linux/sched.h | 2 +- trunk/include/linux/socket.h | 2 +- trunk/include/net/ip_fib.h | 2 - trunk/ipc/mqueue.c | 8 +- trunk/kernel/cgroup.c | 11 +- trunk/kernel/cpuset.c | 13 +- trunk/kernel/debug/debug_core.c | 16 +- trunk/kernel/debug/kdb/kdb_main.c | 48 +- trunk/kernel/sched.c | 8 +- trunk/kernel/sched_fair.c | 25 +- trunk/kernel/sched_stats.h | 20 +- trunk/mm/shmem.c | 10 +- trunk/net/compat.c | 10 +- trunk/net/core/iovec.c | 20 +- trunk/net/core/pktgen.c | 7 +- trunk/net/dccp/ccid.h | 34 +- trunk/net/dccp/ccids/ccid2.c | 23 +- trunk/net/dccp/ccids/ccid2.h | 5 - trunk/net/dccp/ccids/ccid3.c | 12 +- trunk/net/dccp/dccp.h | 5 +- trunk/net/dccp/output.c | 209 +- trunk/net/dccp/proto.c | 21 +- trunk/net/dccp/timer.c | 27 +- trunk/net/ipv4/fib_frontend.c | 2 +- trunk/net/ipv4/fib_hash.c | 18 - trunk/net/ipv4/fib_trie.c | 5 - trunk/net/mac80211/debugfs_key.c | 6 +- trunk/net/mac80211/main.c | 5 +- trunk/net/netfilter/xt_socket.c | 7 +- trunk/net/socket.c | 10 +- trunk/net/sunrpc/rpc_pipe.c | 18 +- trunk/samples/Kconfig | 7 - trunk/samples/Makefile | 2 +- trunk/samples/kdb/Makefile | 1 - trunk/samples/kdb/kdb_hello.c | 60 - trunk/scripts/kconfig/streamline_config.pl | 12 +- trunk/scripts/recordmcount.c | 44 - trunk/scripts/recordmcount.h | 86 +- trunk/security/inode.c | 8 +- trunk/security/selinux/selinuxfs.c | 9 +- trunk/security/smack/smackfs.c | 12 +- 421 files changed, 45236 insertions(+), 11996 deletions(-) delete mode 100644 trunk/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h delete mode 100644 trunk/arch/mips/include/asm/perf_event.h delete mode 100644 trunk/arch/mips/kernel/perf_event.c delete mode 100644 trunk/arch/mips/kernel/perf_event_mipsxx.c create mode 100644 trunk/drivers/staging/dream/Kconfig create mode 100644 trunk/drivers/staging/dream/Makefile create mode 100644 trunk/drivers/staging/dream/TODO create mode 100644 trunk/drivers/staging/dream/camera/Kconfig create mode 100644 trunk/drivers/staging/dream/camera/Makefile create mode 100644 trunk/drivers/staging/dream/camera/msm_camera.c create mode 100644 trunk/drivers/staging/dream/camera/msm_io7x.c create mode 100644 trunk/drivers/staging/dream/camera/msm_io8x.c create mode 100644 trunk/drivers/staging/dream/camera/msm_v4l2.c create mode 100644 trunk/drivers/staging/dream/camera/msm_vfe7x.c create mode 100644 trunk/drivers/staging/dream/camera/msm_vfe7x.h create mode 100644 trunk/drivers/staging/dream/camera/msm_vfe8x.c create mode 100644 trunk/drivers/staging/dream/camera/msm_vfe8x.h create mode 100644 trunk/drivers/staging/dream/camera/msm_vfe8x_proc.c create mode 100644 trunk/drivers/staging/dream/camera/msm_vfe8x_proc.h create mode 100644 trunk/drivers/staging/dream/camera/mt9d112.c create mode 100644 trunk/drivers/staging/dream/camera/mt9d112.h create mode 100644 trunk/drivers/staging/dream/camera/mt9d112_reg.c create mode 100644 trunk/drivers/staging/dream/camera/mt9p012.h create mode 100644 trunk/drivers/staging/dream/camera/mt9p012_fox.c create mode 100644 trunk/drivers/staging/dream/camera/mt9p012_reg.c create mode 100644 trunk/drivers/staging/dream/camera/mt9t013.c create mode 100644 trunk/drivers/staging/dream/camera/mt9t013.h create mode 100644 trunk/drivers/staging/dream/camera/mt9t013_reg.c create mode 100644 trunk/drivers/staging/dream/camera/s5k3e2fx.c create mode 100644 trunk/drivers/staging/dream/camera/s5k3e2fx.h create mode 100644 trunk/drivers/staging/dream/generic_gpio.c create mode 100644 trunk/drivers/staging/dream/gpio_axis.c create mode 100644 trunk/drivers/staging/dream/gpio_event.c create mode 100644 trunk/drivers/staging/dream/gpio_input.c create mode 100644 trunk/drivers/staging/dream/gpio_matrix.c create mode 100644 trunk/drivers/staging/dream/gpio_output.c create mode 100644 trunk/drivers/staging/dream/include/linux/android_pmem.h create mode 100644 trunk/drivers/staging/dream/include/linux/gpio_event.h create mode 100644 trunk/drivers/staging/dream/include/linux/msm_adsp.h create mode 100644 trunk/drivers/staging/dream/include/linux/msm_audio.h create mode 100644 trunk/drivers/staging/dream/include/linux/msm_rpcrouter.h create mode 100644 trunk/drivers/staging/dream/include/linux/wakelock.h create mode 100644 trunk/drivers/staging/dream/include/mach/camera.h create mode 100644 trunk/drivers/staging/dream/include/mach/msm_adsp.h create mode 100644 trunk/drivers/staging/dream/include/mach/msm_rpcrouter.h create mode 100644 trunk/drivers/staging/dream/include/mach/msm_smd.h create mode 100644 trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h create mode 100644 trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h create mode 100644 trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h create mode 100644 trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h create mode 100644 trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h create mode 100644 trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h create mode 100644 trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h create mode 100644 trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h create mode 100644 trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h create mode 100644 trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h create mode 100644 trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h create mode 100644 trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h create mode 100644 trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h create mode 100644 trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h create mode 100644 trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h create mode 100644 trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h create mode 100644 trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h create mode 100644 trunk/drivers/staging/dream/include/media/msm_camera.h create mode 100644 trunk/drivers/staging/dream/pmem.c create mode 100644 trunk/drivers/staging/dream/qdsp5/Makefile create mode 100644 trunk/drivers/staging/dream/qdsp5/adsp.c create mode 100644 trunk/drivers/staging/dream/qdsp5/adsp.h create mode 100644 trunk/drivers/staging/dream/qdsp5/adsp_6210.c create mode 100644 trunk/drivers/staging/dream/qdsp5/adsp_6220.c create mode 100644 trunk/drivers/staging/dream/qdsp5/adsp_6225.c create mode 100644 trunk/drivers/staging/dream/qdsp5/adsp_driver.c create mode 100644 trunk/drivers/staging/dream/qdsp5/adsp_info.c create mode 100644 trunk/drivers/staging/dream/qdsp5/adsp_jpeg_patch_event.c create mode 100644 trunk/drivers/staging/dream/qdsp5/adsp_jpeg_verify_cmd.c create mode 100644 trunk/drivers/staging/dream/qdsp5/adsp_lpm_verify_cmd.c create mode 100644 trunk/drivers/staging/dream/qdsp5/adsp_vfe_patch_event.c create mode 100644 trunk/drivers/staging/dream/qdsp5/adsp_vfe_verify_cmd.c create mode 100644 trunk/drivers/staging/dream/qdsp5/adsp_video_verify_cmd.c create mode 100644 trunk/drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c create mode 100644 trunk/drivers/staging/dream/qdsp5/audio_aac.c create mode 100644 trunk/drivers/staging/dream/qdsp5/audio_amrnb.c create mode 100644 trunk/drivers/staging/dream/qdsp5/audio_evrc.c create mode 100644 trunk/drivers/staging/dream/qdsp5/audio_in.c create mode 100644 trunk/drivers/staging/dream/qdsp5/audio_mp3.c create mode 100644 trunk/drivers/staging/dream/qdsp5/audio_out.c create mode 100644 trunk/drivers/staging/dream/qdsp5/audio_qcelp.c create mode 100644 trunk/drivers/staging/dream/qdsp5/audmgr.c create mode 100644 trunk/drivers/staging/dream/qdsp5/audmgr.h create mode 100644 trunk/drivers/staging/dream/qdsp5/audmgr_new.h create mode 100644 trunk/drivers/staging/dream/qdsp5/audpp.c create mode 100644 trunk/drivers/staging/dream/qdsp5/evlog.h create mode 100644 trunk/drivers/staging/dream/qdsp5/snd.c create mode 100644 trunk/drivers/staging/dream/synaptics_i2c_rmi.c create mode 100644 trunk/drivers/staging/dream/synaptics_i2c_rmi.h delete mode 100644 trunk/drivers/usb/host/ehci-octeon.c delete mode 100644 trunk/drivers/usb/host/octeon2-common.c delete mode 100644 trunk/drivers/usb/host/ohci-octeon.c delete mode 100644 trunk/samples/kdb/Makefile delete mode 100644 trunk/samples/kdb/kdb_hello.c diff --git a/[refs] b/[refs] index b90d976c0b60..6ca86bd74b49 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1840897ab5d39b2e510c610ee262ded79919e718 +refs/heads/master: 4908980b241bc639b71ef47b727b4bc7c0174afe diff --git a/trunk/Documentation/DocBook/kgdb.tmpl b/trunk/Documentation/DocBook/kgdb.tmpl index d71b57fcf116..490d862c5f0d 100644 --- a/trunk/Documentation/DocBook/kgdb.tmpl +++ b/trunk/Documentation/DocBook/kgdb.tmpl @@ -710,18 +710,7 @@ Task Addr Pid Parent [*] cpu State Thread Command A simple shell The kdb core command set A registration API to register additional kdb shell commands. - - A good example of a self-contained kdb module - is the "ftdump" command for dumping the ftrace buffer. See: - kernel/trace/trace_kdb.c - 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. - + A good example of a self-contained kdb module is the "ftdump" command for dumping the ftrace buffer. See: kernel/trace/trace_kdb.c The implementation for kdb_printf() which emits messages directly to I/O drivers, bypassing the kernel log. diff --git a/trunk/Makefile b/trunk/Makefile index 519db43052a0..6b23f1b15fc4 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -204,9 +204,6 @@ ifeq ($(ARCH),x86_64) endif # Additional ARCH settings for sparc -ifeq ($(ARCH),sparc32) - SRCARCH := sparc -endif ifeq ($(ARCH),sparc64) SRCARCH := sparc endif diff --git a/trunk/arch/arm/include/asm/kgdb.h b/trunk/arch/arm/include/asm/kgdb.h index 48066ce9ea34..08265993227f 100644 --- a/trunk/arch/arm/include/asm/kgdb.h +++ b/trunk/arch/arm/include/asm/kgdb.h @@ -70,8 +70,7 @@ extern int kgdb_fault_expected; #define _GP_REGS 16 #define _FP_REGS 8 #define _EXTRA_REGS 2 -#define GDB_MAX_REGS (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS) -#define DBG_MAX_REG_NUM (_GP_REGS + _FP_REGS + _EXTRA_REGS) +#define DBG_MAX_REG_NUM (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS) #define KGDB_MAX_NO_CPUS 1 #define BUFMAX 400 @@ -94,7 +93,7 @@ extern int kgdb_fault_expected; #define _SPT 13 #define _LR 14 #define _PC 15 -#define _CPSR (GDB_MAX_REGS - 1) +#define _CPSR (DBG_MAX_REG_NUM - 1) /* * So that we can denote the end of a frame for tracing, diff --git a/trunk/arch/arm/kernel/kgdb.c b/trunk/arch/arm/kernel/kgdb.c index 778c2f7024ff..d6e8b4d2e60d 100644 --- a/trunk/arch/arm/kernel/kgdb.c +++ b/trunk/arch/arm/kernel/kgdb.c @@ -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 < GDB_MAX_REGS; regno++) + for (regno = 0; regno < DBG_MAX_REG_NUM; regno++) gdb_regs[regno] = 0; /* Otherwise, we have only some registers from switch_to() */ diff --git a/trunk/arch/blackfin/kernel/kgdb.c b/trunk/arch/blackfin/kernel/kgdb.c index edae461b1c54..08bc44ea6883 100644 --- a/trunk/arch/blackfin/kernel/kgdb.c +++ b/trunk/arch/blackfin/kernel/kgdb.c @@ -320,7 +320,7 @@ static void bfin_correct_hw_break(void) } } -static void bfin_disable_hw_debug(struct pt_regs *regs) +void kgdb_disable_hw_debug(struct pt_regs *regs) { /* Disable hardware debugging while we are in kgdb */ bfin_write_WPIACTL(0); @@ -406,7 +406,6 @@ 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, }; diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index 39e534f5a3b0..6b1852f7f972 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -618,15 +618,16 @@ pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, } -static struct dentry * -pfmfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) +static int +pfmfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, + struct vfsmount *mnt) { - return mount_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC); + return get_sb_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC, mnt); } static struct file_system_type pfm_fs_type = { .name = "pfmfs", - .mount = pfmfs_mount, + .get_sb = pfmfs_get_sb, .kill_sb = kill_anon_super, }; diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 67a2fa2caa49..cf8d0945530c 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -4,21 +4,16 @@ 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" @@ -696,9 +691,6 @@ 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 @@ -1342,57 +1334,6 @@ 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 @@ -1511,18 +1452,6 @@ 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 @@ -1999,14 +1928,6 @@ 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 diff --git a/trunk/arch/mips/Kconfig.debug b/trunk/arch/mips/Kconfig.debug index f437cd1fafb8..43dc27997730 100644 --- a/trunk/arch/mips/Kconfig.debug +++ b/trunk/arch/mips/Kconfig.debug @@ -67,15 +67,6 @@ 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 diff --git a/trunk/arch/mips/Makefile b/trunk/arch/mips/Makefile index 7c1102e41fe2..f4a4b663ebb3 100644 --- a/trunk/arch/mips/Makefile +++ b/trunk/arch/mips/Makefile @@ -48,6 +48,9 @@ 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) @@ -156,7 +159,6 @@ 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,) diff --git a/trunk/arch/mips/ar7/gpio.c b/trunk/arch/mips/ar7/gpio.c index 425dfa5d6e12..c32fbb57441a 100644 --- a/trunk/arch/mips/ar7/gpio.c +++ b/trunk/arch/mips/ar7/gpio.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2007 Felix Fietkau * Copyright (C) 2007 Eugene Konev - * Copyright (C) 2009-2010 Florian Fainelli + * Copyright (C) 2009 Florian Fainelli * * 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,16 +37,6 @@ 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) { @@ -61,21 +51,6 @@ 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 = @@ -87,21 +62,6 @@ 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) { @@ -115,24 +75,6 @@ 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", @@ -145,19 +87,7 @@ static struct ar7_gpio_chip ar7_gpio_chip = { } }; -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) +int ar7_gpio_enable(unsigned gpio) { void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE; @@ -165,26 +95,9 @@ static inline int ar7_gpio_enable_ar7(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); -static inline int ar7_gpio_disable_ar7(unsigned gpio) +int ar7_gpio_disable(unsigned gpio) { void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE; @@ -192,159 +105,27 @@ static inline int ar7_gpio_disable_ar7(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); -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) +static 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; - } - gpch->regs = ioremap_nocache(AR7_REGS_GPIO, + ar7_gpio_chip.regs = ioremap_nocache(AR7_REGS_GPIO, AR7_REGS_GPIO + 0x10); - if (!gpch->regs) { - printk(KERN_ERR "%s: failed to ioremap regs\n", - gpch->chip.label); + if (!ar7_gpio_chip.regs) { + printk(KERN_ERR "ar7-gpio: failed to ioremap regs\n"); return -ENOMEM; } - ret = gpiochip_add(&gpch->chip); + ret = gpiochip_add(&ar7_gpio_chip.chip); if (ret) { - printk(KERN_ERR "%s: failed to add gpiochip\n", - gpch->chip.label); + printk(KERN_ERR "ar7-gpio: failed to add gpiochip\n"); return ret; } - printk(KERN_INFO "%s: registered %d GPIOs\n", - gpch->chip.label, gpch->chip.ngpio); - - if (ar7_is_titan()) - titan_gpio_init(); - + printk(KERN_INFO "ar7-gpio: registered %d GPIOs\n", + ar7_gpio_chip.chip.ngpio); return ret; } +arch_initcall(ar7_gpio_init); diff --git a/trunk/arch/mips/ar7/platform.c b/trunk/arch/mips/ar7/platform.c index 7d2fab392327..0da5b2b8dd88 100644 --- a/trunk/arch/mips/ar7/platform.c +++ b/trunk/arch/mips/ar7/platform.c @@ -357,11 +357,6 @@ 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", @@ -500,9 +495,6 @@ 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; } } @@ -568,51 +560,6 @@ 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; @@ -627,9 +574,6 @@ 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) diff --git a/trunk/arch/mips/ar7/prom.c b/trunk/arch/mips/ar7/prom.c index 23818d299127..52385790e5c1 100644 --- a/trunk/arch/mips/ar7/prom.c +++ b/trunk/arch/mips/ar7/prom.c @@ -246,8 +246,6 @@ 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))) diff --git a/trunk/arch/mips/ar7/setup.c b/trunk/arch/mips/ar7/setup.c index f20b53e597c4..3a801d2cb6e5 100644 --- a/trunk/arch/mips/ar7/setup.c +++ b/trunk/arch/mips/ar7/setup.c @@ -23,7 +23,6 @@ #include #include #include -#include static void ar7_machine_restart(char *command) { @@ -50,8 +49,6 @@ 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)"; @@ -59,17 +56,6 @@ 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)"; } diff --git a/trunk/arch/mips/bcm63xx/cpu.c b/trunk/arch/mips/bcm63xx/cpu.c index 7c7e4d4486ce..cbb7caf86d77 100644 --- a/trunk/arch/mips/bcm63xx/cpu.c +++ b/trunk/arch/mips/bcm63xx/cpu.c @@ -10,9 +10,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -298,24 +296,26 @@ void __init bcm63xx_cpu_init(void) expected_cpu_id = 0; switch (c->cputype) { - 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; - } + /* + * 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; break; - case CPU_BMIPS32: + case CPU_BCM6345: expected_cpu_id = BCM6345_CPU_ID; bcm63xx_regs_base = bcm96345_regs_base; bcm63xx_irqs = bcm96345_irqs; break; - case CPU_BMIPS4350: + case CPU_BCM6348: + expected_cpu_id = BCM6348_CPU_ID; + bcm63xx_regs_base = bcm96348_regs_base; + bcm63xx_irqs = bcm96348_irqs; + break; + case CPU_BCM6358: expected_cpu_id = BCM6358_CPU_ID; bcm63xx_regs_base = bcm96358_regs_base; bcm63xx_irqs = bcm96358_irqs; diff --git a/trunk/arch/mips/cavium-octeon/Kconfig b/trunk/arch/mips/cavium-octeon/Kconfig index caae22858163..47323ca452dc 100644 --- a/trunk/arch/mips/cavium-octeon/Kconfig +++ b/trunk/arch/mips/cavium-octeon/Kconfig @@ -3,17 +3,6 @@ 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 @@ -98,15 +87,3 @@ 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 diff --git a/trunk/arch/mips/cavium-octeon/csrc-octeon.c b/trunk/arch/mips/cavium-octeon/csrc-octeon.c index 26bf71130bf8..b6847c8e0ddd 100644 --- a/trunk/arch/mips/cavium-octeon/csrc-octeon.c +++ b/trunk/arch/mips/cavium-octeon/csrc-octeon.c @@ -4,18 +4,14 @@ * for more details. * * Copyright (C) 2007 by Ralf Baechle - * Copyright (C) 2009, 2010 Cavium Networks, Inc. */ #include #include -#include -#include #include #include #include -#include /* * Set the current core's cvmcount counter to the value of the @@ -23,23 +19,11 @@ * 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)); @@ -49,20 +33,8 @@ void octeon_init_cvmcount(void) * Loop several times so we are executing from the cache, * which should give more deterministic timing. */ - 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); - } + while (loops--) + write_c0_cvmcount(cvmx_read_csr(CVMX_IPD_CLK_COUNT)); local_irq_restore(flags); } @@ -105,7 +77,7 @@ unsigned long long notrace sched_clock(void) void __init plat_time_init(void) { clocksource_mips.rating = 300; - clocksource_set_clock(&clocksource_mips, octeon_get_clock_rate()); + clocksource_set_clock(&clocksource_mips, mips_hpt_frequency); clocksource_register(&clocksource_mips); } diff --git a/trunk/arch/mips/cavium-octeon/dma-octeon.c b/trunk/arch/mips/cavium-octeon/dma-octeon.c index 1abb66caaa1d..d22b5a2d64f4 100644 --- a/trunk/arch/mips/cavium-octeon/dma-octeon.c +++ b/trunk/arch/mips/cavium-octeon/dma-octeon.c @@ -8,342 +8,335 @@ * Copyright (C) 2005 Ilya A. Volynets-Evenbakh * swiped from i386, and cloned for MIPS by Geert, polished by Ralf. * IP32 changes by Ilya. - * Copyright (C) 2010 Cavium Networks, Inc. + * Cavium Networks: Create new dma setup for Cavium Networks Octeon based on + * the kernels original. */ -#include -#include -#include -#include #include -#include #include +#include +#include +#include +#include +#include -#include +#include +#include #include - -#ifdef CONFIG_PCI -#include #include #include -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; -} - -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); -} - -static phys_addr_t octeon_gen1_dma_to_phys(struct device *dev, dma_addr_t daddr) -{ - daddr = octeon_hole_dma_to_phys(daddr); - - if (daddr >= 0x10000000ull && daddr < 0x20000000ull) - daddr += 0x400000000ull; - - return daddr; -} +#include -static dma_addr_t octeon_big_phys_to_dma(struct device *dev, phys_addr_t paddr) -{ - 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 */ +#ifdef CONFIG_PCI +#include +#endif -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(); +#define BAR2_PCI_ADDRESS 0x8000000000ul - return 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 */ +}; -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(); - return r; -} +#ifdef CONFIG_PCI +static DEFINE_RAW_SPINLOCK(bar1_lock); +static struct bar1_index_state bar1_state[32]; +#endif -static void octeon_dma_sync_single_for_device(struct device *dev, - dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) +dma_addr_t octeon_map_dma_mem(struct device *dev, void *ptr, size_t size) { - swiotlb_sync_single_for_device(dev, dma_handle, size, direction); +#ifndef CONFIG_PCI + /* Without PCI/PCIe this function can be called for Octeon internal + devices such as USB. These devices all support 64bit addressing */ 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; -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(); -} - -static void *octeon_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp) -{ - void *ret; + /* + * 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; + } - if (dma_alloc_from_coherent(dev, size, dma_handle, &ret)) - return ret; + /* + * 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; - /* ignore region specifiers */ - gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM); + 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; -#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 -#ifdef CONFIG_ZONE_DMA32 - if (dev->coherent_dma_mask <= DMA_BIT_MASK(32)) - gfp |= __GFP_DMA32; - else + 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 - ; - - /* Don't invoke OOM killer */ - gfp |= __GFP_NORETRY; - - ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp); - - mb(); - - return ret; -} - -static void octeon_dma_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - int order = get_order(size); + 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; - if (dma_release_from_coherent(dev, order, vaddr)) - return; + 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; + } +#endif + /* Continued below switch statement */ + break; - swiotlb_free_coherent(dev, size, vaddr, dma_handle); -} + default: + panic("dma_map_single: Invalid octeon_dma_bar_type\n"); + } -static dma_addr_t octeon_unity_phys_to_dma(struct device *dev, phys_addr_t paddr) -{ - return paddr; -} + /* 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"); -static phys_addr_t octeon_unity_dma_to_phys(struct device *dev, dma_addr_t daddr) -{ - return daddr; -} + 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; + } + } -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); -}; + /* 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; + } + } -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); + pr_err("dma_map_single: " + "Can't find empty BAR1 index for physical mapping 0x%llx\n", + (unsigned long long) physical); - return ops->phys_to_dma(dev, paddr); +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 } -EXPORT_SYMBOL(phys_to_dma); -phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) +void octeon_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr) { - 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 +#ifndef CONFIG_PCI /* - * For OCTEON_DMA_BAR_TYPE_SMALL, size the iotlb at 1/4 memory - * size to a maximum of 64MB + * Without PCI/PCIe this function can be called for Octeon internal + * devices such as USB. These devices all support 64bit addressing. */ - 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); + return; +#else + unsigned long flags; + uint64_t index; - 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; + /* + * Platform devices, such as the internal USB, skip all + * translation and use Octeon physical addresses directly. + */ + if (dev->bus == &platform_bus_type) + return; -void __init octeon_pci_dma_init(void) -{ switch (octeon_dma_bar_type) { case OCTEON_DMA_BAR_TYPE_PCIE: - _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; + /* Nothing to do, all mappings are static */ + goto done; + case OCTEON_DMA_BAR_TYPE_BIG: - _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; +#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 */ break; + case OCTEON_DMA_BAR_TYPE_SMALL: - _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; +#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 */ break; + default: - BUG(); + panic("dma_unmap_single: Invalid octeon_dma_bar_type\n"); } - octeon_pci_dma_map_ops = &_octeon_pci_dma_map_ops.dma_map_ops; + + 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 } -#endif /* CONFIG_PCI */ diff --git a/trunk/arch/mips/cavium-octeon/executive/cvmx-l2c.c b/trunk/arch/mips/cavium-octeon/executive/cvmx-l2c.c index d38246e33ddb..6abe56f1e097 100644 --- a/trunk/arch/mips/cavium-octeon/executive/cvmx-l2c.c +++ b/trunk/arch/mips/cavium-octeon/executive/cvmx-l2c.c @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -42,7 +42,13 @@ * if multiple applications or operating systems are running, then it * is up to the user program to coordinate between them. */ -cvmx_spinlock_t cvmx_l2c_spinlock; +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)); +} int cvmx_l2c_get_core_way_partition(uint32_t core) { @@ -52,9 +58,6 @@ 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. @@ -68,13 +71,17 @@ 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; } @@ -88,50 +95,48 @@ 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 on some chips */ - if (mask == valid_mask && !OCTEON_IS_MODEL(OCTEON_CN63XX)) + /* A UMSK setting which blocks all L2C Ways is an error. */ + if (mask == valid_mask) return -1; /* Validate the core number */ if (core >= cvmx_octeon_num_cores()) return -1; - if (OCTEON_IS_MODEL(OCTEON_CN63XX)) { - cvmx_write_csr(CVMX_L2C_WPAR_PPX(core), mask); - return 0; - } + /* 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; - /* - * 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; @@ -141,137 +146,84 @@ int cvmx_l2c_set_hw_way_partition(uint32_t mask) { uint32_t valid_mask; - valid_mask = (0x1 << cvmx_l2c_get_num_assoc()) - 1; + 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; + 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)) + /* 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) return -1; - 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); + cvmx_write_csr(CVMX_L2C_SPAR4, + (cvmx_read_csr(CVMX_L2C_SPAR4) & ~0xFF) | mask); return 0; } int cvmx_l2c_get_hw_way_partition(void) { - 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); + 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) { - if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX)) { - union cvmx_l2c_pfctl pfctl; + 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; + switch (counter) { + case 0: + pfctl.s.cnt0sel = event; + pfctl.s.cnt0ena = 1; + if (!cvmx_octeon_is_pass1()) pfctl.s.cnt0rdclr = clear_on_read; - break; - case 1: - pfctl.s.cnt1sel = event; - pfctl.s.cnt1ena = 1; + break; + case 1: + pfctl.s.cnt1sel = event; + pfctl.s.cnt1ena = 1; + if (!cvmx_octeon_is_pass1()) pfctl.s.cnt1rdclr = clear_on_read; - break; - case 2: - pfctl.s.cnt2sel = event; - pfctl.s.cnt2ena = 1; + break; + case 2: + pfctl.s.cnt2sel = event; + pfctl.s.cnt2ena = 1; + if (!cvmx_octeon_is_pass1()) pfctl.s.cnt2rdclr = clear_on_read; - break; - case 3: - default: - pfctl.s.cnt3sel = event; - pfctl.s.cnt3ena = 1; + break; + case 3: + default: + pfctl.s.cnt3sel = event; + pfctl.s.cnt3ena = 1; + if (!cvmx_octeon_is_pass1()) pfctl.s.cnt3rdclr = clear_on_read; - break; - } - - 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); + break; } + + cvmx_write_csr(CVMX_L2C_PFCTL, pfctl.u64); } uint64_t cvmx_l2c_read_perf(uint32_t counter) { switch (counter) { case 0: - 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; - } + return cvmx_read_csr(CVMX_L2C_PFC0); case 1: - 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; - } + return cvmx_read_csr(CVMX_L2C_PFC1); case 2: - 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; - } + return cvmx_read_csr(CVMX_L2C_PFC2); case 3: default: - 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; - } + return cvmx_read_csr(CVMX_L2C_PFC3); } } @@ -288,7 +240,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; @@ -307,100 +259,67 @@ static void fault_in(uint64_t addr, int len) int cvmx_l2c_lock_line(uint64_t addr) { - 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; - } + 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); - /* 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; - } + addr &= ~CVMX_CACHE_LINE_MASK; - /* 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; + /* 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 { - int retval = 0; - union cvmx_l2c_dbg l2cdbg; - union cvmx_l2c_lckbase lckbase; - union cvmx_l2c_lckoff lckoff; - union cvmx_l2t_err l2t_err; - - cvmx_spinlock_lock(&cvmx_l2c_spinlock); - - l2cdbg.u64 = 0; - lckbase.u64 = 0; - lckoff.u64 = 0; - - /* 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); + lckbase.s.lck_base = addr >> 7; + } - addr &= ~CVMX_CACHE_LINE_MASK; + lckbase.s.lck_ena = 1; + cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64); + cvmx_read_csr(CVMX_L2C_LCKBASE); /* Make sure it gets there */ - /* 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; - } + fault_in(addr, CVMX_CACHE_LINE_SIZE); - lckbase.s.lck_ena = 1; - cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64); - /* Make sure it gets there */ - cvmx_read_csr(CVMX_L2C_LCKBASE); + lckbase.s.lck_ena = 0; + cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64); + cvmx_read_csr(CVMX_L2C_LCKBASE); /* Make sure it gets there */ - fault_in(addr, CVMX_CACHE_LINE_SIZE); + /* Stop being debug core */ + cvmx_write_csr(CVMX_L2C_DBG, 0); + cvmx_read_csr(CVMX_L2C_DBG); - lckbase.s.lck_ena = 0; - cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64); - /* Make sure it gets there */ - cvmx_read_csr(CVMX_L2C_LCKBASE); + 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 */ - /* Stop being debug core */ - cvmx_write_csr(CVMX_L2C_DBG, 0); - cvmx_read_csr(CVMX_L2C_DBG); + cvmx_spinlock_unlock(&cvmx_l2c_spinlock); - 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; - } + return retval; } int cvmx_l2c_lock_mem_region(uint64_t start, uint64_t len) @@ -417,6 +336,7 @@ int cvmx_l2c_lock_mem_region(uint64_t start, uint64_t len) start += CVMX_CACHE_LINE_SIZE; len -= CVMX_CACHE_LINE_SIZE; } + return retval; } @@ -424,73 +344,80 @@ 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); - 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); - } + 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); } - } 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; - 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; + uint32_t index = cvmx_l2c_address_to_index(address); - uint32_t index = cvmx_l2c_address_to_index(address); + 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); - /* 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); + 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; - if (tag.s.V && (tag.s.addr == tag_addr)) { - cvmx_l2c_flush_line(assoc, index); - return tag.s.L; - } + 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; } } + cvmx_spinlock_unlock(&cvmx_l2c_spinlock); return 0; } @@ -518,49 +445,48 @@ 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 @@ -577,7 +503,7 @@ union __cvmx_l2c_tag { static union __cvmx_l2c_tag __read_l2_tag(uint64_t assoc, uint64_t index) { - uint64_t debug_tag_addr = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, (index << 7) + 96); + uint64_t debug_tag_addr = (((1ULL << 63) | (index << 7)) + 96); uint64_t core = cvmx_get_core_num(); union __cvmx_l2c_tag tag_val; uint64_t dbg_addr = CVMX_L2C_DBG; @@ -586,15 +512,12 @@ 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. @@ -603,139 +526,112 @@ 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\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"); + 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"); local_irq_restore(flags); - 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_l2c_get_tag association out of range\n"); + cvmx_dprintf + ("ERROR: cvmx_get_l2c_tag association out of range\n"); return tag; } if ((int)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()); + cvmx_dprintf("ERROR: cvmx_get_l2c_tag " + "index out of range (arg: %d, max: %d\n", + index, cvmx_l2c_get_num_sets()); return tag; } - 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; + /* __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 { - 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__); - } + 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; - int indxalias = 0; + union cvmx_l2c_cfg l2c_cfg; + l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG); - 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_TAG_ADDR_ALIAS_SHIFT); - } + if (l2c_cfg.s.idxalias) { + idx ^= + ((addr & CVMX_L2C_ALIAS_MASK) >> + CVMX_L2C_TAG_ADDR_ALIAS_SHIFT); } idx &= CVMX_L2C_IDX_MASK; return idx; @@ -756,9 +652,10 @@ 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) || OCTEON_IS_MODEL(OCTEON_CN63XX)) + else if (OCTEON_IS_MODEL(OCTEON_CN38XX)) 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 */ @@ -769,6 +666,7 @@ 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 */ @@ -784,11 +682,8 @@ 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; @@ -798,42 +693,11 @@ int cvmx_l2c_get_num_assoc(void) } /* Check to see if part of the cache is disabled */ - 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; - } + if (cvmx_fuse_read(265)) + l2_assoc = l2_assoc >> 2; + else if (cvmx_fuse_read(264)) + l2_assoc = l2_assoc >> 1; + return l2_assoc; } @@ -847,54 +711,24 @@ int cvmx_l2c_get_num_assoc(void) */ void cvmx_l2c_flush_line(uint32_t assoc, uint32_t index) { - /* 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; - } + union cvmx_l2c_dbg l2cdbg; - /* 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.u64 = 0; + l2cdbg.s.ppnum = cvmx_get_core_num(); + l2cdbg.s.finv = 1; - 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); - } + 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); } diff --git a/trunk/arch/mips/cavium-octeon/octeon-platform.c b/trunk/arch/mips/cavium-octeon/octeon-platform.c index cecaf62aef32..62ac30eef5e8 100644 --- a/trunk/arch/mips/cavium-octeon/octeon-platform.c +++ b/trunk/arch/mips/cavium-octeon/octeon-platform.c @@ -3,15 +3,13 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2004-2010 Cavium Networks + * Copyright (C) 2004-2009 Cavium Networks * Copyright (C) 2008 Wind River Systems */ #include #include #include -#include -#include #include #include @@ -200,7 +198,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_io_clock_rate(); + octeon_i2c_data[port].sys_freq = octeon_get_clock_rate(); /*FIXME: should be examined. At the moment is set for 100Khz */ octeon_i2c_data[port].i2c_freq = 100000; @@ -303,10 +301,6 @@ 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; @@ -338,108 +332,6 @@ static int __init octeon_mgmt_device_init(void) } 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 "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Platform driver for Octeon SOC"); diff --git a/trunk/arch/mips/cavium-octeon/serial.c b/trunk/arch/mips/cavium-octeon/serial.c index 057f0ae88c99..12dbf533b77d 100644 --- a/trunk/arch/mips/cavium-octeon/serial.c +++ b/trunk/arch/mips/cavium-octeon/serial.c @@ -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 = octeon_get_io_clock_rate(); + p->uartclk = mips_hpt_frequency; p->serial_in = octeon_serial_in; p->serial_out = octeon_serial_out; } diff --git a/trunk/arch/mips/cavium-octeon/setup.c b/trunk/arch/mips/cavium-octeon/setup.c index b0c3686c96dd..69197cb6c7ea 100644 --- a/trunk/arch/mips/cavium-octeon/setup.c +++ b/trunk/arch/mips/cavium-octeon/setup.c @@ -33,7 +33,6 @@ #include #include -#include #ifdef CONFIG_CAVIUM_DECODE_RSL extern void cvmx_interrupt_rsl_decode(void); @@ -97,21 +96,12 @@ int octeon_is_pci_host(void) */ uint64_t octeon_get_clock_rate(void) { - struct cvmx_sysinfo *sysinfo = cvmx_sysinfo_get(); - - return sysinfo->cpu_clock_hz; + if (octeon_is_simulation()) + octeon_bootinfo->eclock_hz = 6000000; + return octeon_bootinfo->eclock_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 @@ -356,18 +346,8 @@ 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. 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 The write buffer threshold. */ + 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 @@ -385,13 +365,14 @@ 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); @@ -435,41 +416,6 @@ 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. @@ -533,6 +479,33 @@ 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(); @@ -767,31 +740,6 @@ 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(); diff --git a/trunk/arch/mips/include/asm/atomic.h b/trunk/arch/mips/include/asm/atomic.h index 4a02fe891ab6..47d87da379f9 100644 --- a/trunk/arch/mips/include/asm/atomic.h +++ b/trunk/arch/mips/include/asm/atomic.h @@ -64,16 +64,18 @@ static __inline__ void atomic_add(int i, atomic_t * v) } else if (kernel_uses_llsc) { int temp; - 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)); + __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)); } else { unsigned long flags; @@ -107,16 +109,18 @@ static __inline__ void atomic_sub(int i, atomic_t * v) } else if (kernel_uses_llsc) { int temp; - 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)); + __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)); } else { unsigned long flags; @@ -152,19 +156,20 @@ static __inline__ int atomic_add_return(int i, atomic_t * v) } else if (kernel_uses_llsc) { int temp; - 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; + __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"); } else { unsigned long flags; @@ -200,24 +205,23 @@ 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; - 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; + __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"); } else { unsigned long flags; @@ -275,9 +279,12 @@ 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, 1b \n" + " beqz %0, 2f \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) @@ -436,16 +443,18 @@ static __inline__ void atomic64_add(long i, atomic64_t * v) } else if (kernel_uses_llsc) { long temp; - 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)); + __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)); } else { unsigned long flags; @@ -479,16 +488,18 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v) } else if (kernel_uses_llsc) { long temp; - 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)); + __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)); } else { unsigned long flags; @@ -524,19 +535,20 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v) } else if (kernel_uses_llsc) { long temp; - 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; + __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"); } else { unsigned long flags; @@ -575,19 +587,20 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) } else if (kernel_uses_llsc) { long temp; - 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; + __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"); } else { unsigned long flags; @@ -645,9 +658,12 @@ 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, 1b \n" + " beqz %0, 2f \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) diff --git a/trunk/arch/mips/include/asm/bitops.h b/trunk/arch/mips/include/asm/bitops.h index 50b4ef288c53..b0ce7ca2851f 100644 --- a/trunk/arch/mips/include/asm/bitops.h +++ b/trunk/arch/mips/include/asm/bitops.h @@ -73,26 +73,30 @@ 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)) { - 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)); + __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)); #endif /* CONFIG_CPU_MIPSR2 */ } else if (kernel_uses_llsc) { - 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)); + __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)); } else { volatile unsigned long *a = addr; unsigned long mask; @@ -130,30 +134,34 @@ 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))); + : "=&r" (temp), "=m" (*m) + : "ir" (~(1UL << bit)), "m" (*m)); #ifdef CONFIG_CPU_MIPSR2 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { - 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)); + __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)); #endif /* CONFIG_CPU_MIPSR2 */ } else if (kernel_uses_llsc) { - 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)); + __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)); } else { volatile unsigned long *a = addr; unsigned long mask; @@ -205,22 +213,24 @@ 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)); + : "=&r" (temp), "=m" (*m) + : "ir" (1UL << bit), "m" (*m)); } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; - 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)); + __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)); } else { volatile unsigned long *a = addr; unsigned long mask; @@ -262,26 +272,30 @@ 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) + : "=&r" (temp), "=m" (*m), "=&r" (res) + : "r" (1UL << bit), "m" (*m) : "memory"); } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; - 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); + __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"); } else { volatile unsigned long *a = addr; unsigned long mask; @@ -326,26 +340,30 @@ 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) + : "=&r" (temp), "=m" (*m), "=&r" (res) + : "r" (1UL << bit), "m" (*m) : "memory"); } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; - 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); + __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"); } else { volatile unsigned long *a = addr; unsigned long mask; @@ -392,43 +410,49 @@ 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) + : "=&r" (temp), "=m" (*m), "=&r" (res) + : "r" (1UL << bit), "m" (*m) : "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; - 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)); + __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"); #endif } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; - 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); + __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"); } else { volatile unsigned long *a = addr; unsigned long mask; @@ -475,26 +499,30 @@ 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) + : "=&r" (temp), "=m" (*m), "=&r" (res) + : "r" (1UL << bit), "m" (*m) : "memory"); } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; - 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); + __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"); } else { volatile unsigned long *a = addr; unsigned long mask; diff --git a/trunk/arch/mips/include/asm/bootinfo.h b/trunk/arch/mips/include/asm/bootinfo.h index 35cd1bab69c3..15a8ef0707c6 100644 --- a/trunk/arch/mips/include/asm/bootinfo.h +++ b/trunk/arch/mips/include/asm/bootinfo.h @@ -125,16 +125,4 @@ 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 */ diff --git a/trunk/arch/mips/include/asm/cmpxchg.h b/trunk/arch/mips/include/asm/cmpxchg.h index d8d1c2805ac7..2d28017e95d0 100644 --- a/trunk/arch/mips/include/asm/cmpxchg.h +++ b/trunk/arch/mips/include/asm/cmpxchg.h @@ -44,9 +44,12 @@ " move $1, %z4 \n" \ " .set mips3 \n" \ " " st " $1, %1 \n" \ - " beqz $1, 1b \n" \ - " .set pop \n" \ + " beqz $1, 3f \n" \ "2: \n" \ + " .subsection 2 \n" \ + "3: b 1b \n" \ + " .previous \n" \ + " .set pop \n" \ : "=&r" (__ret), "=R" (*m) \ : "R" (*m), "Jr" (old), "Jr" (new) \ : "memory"); \ diff --git a/trunk/arch/mips/include/asm/cpu.h b/trunk/arch/mips/include/asm/cpu.h index 06d59dcbe243..b201a8f5b127 100644 --- a/trunk/arch/mips/include/asm/cpu.h +++ b/trunk/arch/mips/include/asm/cpu.h @@ -111,16 +111,14 @@ * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM */ -#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 +#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 /* * These are the PRID's for when 23:16 == PRID_COMP_CAVIUM @@ -133,7 +131,6 @@ #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 @@ -226,14 +223,15 @@ 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_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350, - CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, + CPU_ALCHEMY, CPU_PR4450, CPU_BCM3302, CPU_BCM4710, + CPU_BCM6338, CPU_BCM6345, CPU_BCM6348, CPU_BCM6358, + 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_OCTEON2, + CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS, CPU_LAST }; diff --git a/trunk/arch/mips/include/asm/device.h b/trunk/arch/mips/include/asm/device.h index c94fafba9e62..06746c5e8099 100644 --- a/trunk/arch/mips/include/asm/device.h +++ b/trunk/arch/mips/include/asm/device.h @@ -3,17 +3,4 @@ * * This file is released under the GPLv2 */ -#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*/ +#include diff --git a/trunk/arch/mips/include/asm/dma-mapping.h b/trunk/arch/mips/include/asm/dma-mapping.h index 655f849bd08d..18fbf7af8e93 100644 --- a/trunk/arch/mips/include/asm/dma-mapping.h +++ b/trunk/arch/mips/include/asm/dma-mapping.h @@ -5,41 +5,51 @@ #include #include -#include - -extern struct dma_map_ops *mips_dma_map_ops; - -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; -} - -static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) -{ - if (!dev->dma_mask) - return 0; +void *dma_alloc_noncoherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag); - return addr + size <= *dev->dma_mask; -} +void dma_free_noncoherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle); -static inline void dma_mark_clean(void *addr, size_t size) {} +void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag); -#include +void dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle); -static inline int dma_supported(struct device *dev, u64 mask) +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) { - struct dma_map_ops *ops = get_dma_ops(dev); - return ops->dma_supported(dev, mask); + dma_unmap_single(dev, dma_address, size, direction); } -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); -} +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_set_mask(struct device *dev, u64 mask) @@ -55,34 +65,4 @@ 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 */ diff --git a/trunk/arch/mips/include/asm/dma.h b/trunk/arch/mips/include/asm/dma.h index 2d47da62d5a7..1353c81065d1 100644 --- a/trunk/arch/mips/include/asm/dma.h +++ b/trunk/arch/mips/include/asm/dma.h @@ -91,10 +91,7 @@ #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 */ diff --git a/trunk/arch/mips/include/asm/local.h b/trunk/arch/mips/include/asm/local.h index fffc8307a80a..bdcdef02d147 100644 --- a/trunk/arch/mips/include/asm/local.h +++ b/trunk/arch/mips/include/asm/local.h @@ -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) (atomic_long_xchg((&(l)->a), (n))) +#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n))) /** * local_add_unless - add unless the number is a given value diff --git a/trunk/arch/mips/include/asm/mach-ar7/ar7.h b/trunk/arch/mips/include/asm/mach-ar7/ar7.h index 7919d76186bf..483ffea9ecb1 100644 --- a/trunk/arch/mips/include/asm/mach-ar7/ar7.h +++ b/trunk/arch/mips/include/asm/mach-ar7/ar7.h @@ -39,7 +39,6 @@ #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) @@ -51,14 +50,6 @@ #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 @@ -68,30 +59,15 @@ #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 @@ -119,29 +95,14 @@ 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 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); + return readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) & 0xffff; } static inline u8 ar7_chip_rev(void) { - return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + (ar7_is_titan() ? 0x24 : - 0x14))) >> 16) & 0xff; + return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) >> 16) & 0xff; } struct clk { @@ -200,8 +161,4 @@ 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__ */ diff --git a/trunk/arch/mips/include/asm/mach-ar7/gpio.h b/trunk/arch/mips/include/asm/mach-ar7/gpio.h index c177cd1eed25..abc317c0372e 100644 --- a/trunk/arch/mips/include/asm/mach-ar7/gpio.h +++ b/trunk/arch/mips/include/asm/mach-ar7/gpio.h @@ -22,8 +22,7 @@ #include #define AR7_GPIO_MAX 32 -#define TITAN_GPIO_MAX 51 -#define NR_BUILTIN_GPIO TITAN_GPIO_MAX +#define NR_BUILTIN_GPIO AR7_GPIO_MAX #define gpio_to_irq(gpio) -1 diff --git a/trunk/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/trunk/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h index 0d5a42b5f47a..b952fc7215e2 100644 --- a/trunk/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h +++ b/trunk/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h @@ -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) +#define kernel_uses_smartmips_rixi (cpu_data[0].cputype == CPU_CAVIUM_OCTEON_PLUS) #define ARCH_HAS_IRQ_PER_CPU 1 #define ARCH_HAS_SPINLOCK_PREFETCH 1 @@ -81,10 +81,4 @@ 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 diff --git a/trunk/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h b/trunk/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h index be8fb4240cec..17d579471ec4 100644 --- a/trunk/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h +++ b/trunk/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h @@ -15,40 +15,41 @@ struct device; -extern void octeon_pci_dma_init(void); +dma_addr_t octeon_map_dma_mem(struct device *, void *, size_t); +void octeon_unmap_dma_mem(struct device *, dma_addr_t); static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) { - BUG(); + return octeon_map_dma_mem(dev, addr, size); } static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) { - BUG(); + return octeon_map_dma_mem(dev, page_address(page), PAGE_SIZE); } static inline unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) { - BUG(); + return 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) { - BUG(); + octeon_unmap_dma_mem(dev, dma_addr); } static inline int plat_dma_supported(struct device *dev, u64 mask) { - BUG(); + return 1; } static inline void plat_extra_sync_for_device(struct device *dev) { - BUG(); + mb(); } static inline int plat_device_is_coherent(struct device *dev) @@ -59,14 +60,7 @@ 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) { - BUG(); + return dma_addr == -1; } -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 */ diff --git a/trunk/arch/mips/include/asm/mach-ip27/dma-coherence.h b/trunk/arch/mips/include/asm/mach-ip27/dma-coherence.h index 016d0989b141..d3d04018a858 100644 --- a/trunk/arch/mips/include/asm/mach-ip27/dma-coherence.h +++ b/trunk/arch/mips/include/asm/mach-ip27/dma-coherence.h @@ -26,15 +26,14 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, return pa; } -static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, - struct page *page) +static 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 inline unsigned long plat_dma_addr_to_phys(struct device *dev, +static unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) { return dma_addr & ~(0xffUL << 56); diff --git a/trunk/arch/mips/include/asm/mach-ip32/dma-coherence.h b/trunk/arch/mips/include/asm/mach-ip32/dma-coherence.h index c8fb5aacf50a..37855955b313 100644 --- a/trunk/arch/mips/include/asm/mach-ip32/dma-coherence.h +++ b/trunk/arch/mips/include/asm/mach-ip32/dma-coherence.h @@ -37,8 +37,7 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, return pa; } -static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, - struct page *page) +static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) { dma_addr_t pa; @@ -51,7 +50,7 @@ static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, } /* This is almost certainly wrong but it's what dma-ip32.c used to use */ -static inline unsigned long plat_dma_addr_to_phys(struct device *dev, +static unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) { unsigned long addr = dma_addr & RAM_OFFSET_MASK; diff --git a/trunk/arch/mips/include/asm/mach-jazz/dma-coherence.h b/trunk/arch/mips/include/asm/mach-jazz/dma-coherence.h index 302101b54acb..f93aee59454a 100644 --- a/trunk/arch/mips/include/asm/mach-jazz/dma-coherence.h +++ b/trunk/arch/mips/include/asm/mach-jazz/dma-coherence.h @@ -12,24 +12,23 @@ struct device; -static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) +static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) { return vdma_alloc(virt_to_phys(addr), size); } -static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, - struct page *page) +static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) { return vdma_alloc(page_to_phys(page), PAGE_SIZE); } -static inline unsigned long plat_dma_addr_to_phys(struct device *dev, +static unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) { return vdma_log2phys(dma_addr); } -static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, +static 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); diff --git a/trunk/arch/mips/include/asm/mipsregs.h b/trunk/arch/mips/include/asm/mipsregs.h index 4d9870975382..335474c155f6 100644 --- a/trunk/arch/mips/include/asm/mipsregs.h +++ b/trunk/arch/mips/include/asm/mipsregs.h @@ -1040,12 +1040,6 @@ 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) @@ -1088,51 +1082,6 @@ 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 */ diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-agl-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-agl-defs.h index 30d68f2365e0..ec94b9ab7be1 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-agl-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-agl-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,100 +28,152 @@ #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_RX_INBND(offset) (CVMX_ADD_IO_SEG(0x00011800E0000060ull) + ((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_CLK(offset) (CVMX_ADD_IO_SEG(0x00011800E0000208ull) + ((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 (CVMX_ADD_IO_SEG(0x00011800E0000500ull)) -#define CVMX_AGL_GMX_TX_JAM (CVMX_ADD_IO_SEG(0x00011800E0000490ull)) -#define CVMX_AGL_GMX_TX_LFSR (CVMX_ADD_IO_SEG(0x00011800E00004F8ull)) -#define CVMX_AGL_GMX_TX_OVR_BP (CVMX_ADD_IO_SEG(0x00011800E00004C8ull)) -#define CVMX_AGL_GMX_TX_PAUSE_PKT_DMAC (CVMX_ADD_IO_SEG(0x00011800E00004A0ull)) -#define CVMX_AGL_GMX_TX_PAUSE_PKT_TYPE (CVMX_ADD_IO_SEG(0x00011800E00004A8ull)) -#define CVMX_AGL_PRTX_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0002000ull) + ((offset) & 1) * 8) +#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 \ + CVMX_ADD_IO_SEG(0x00011800E0000500ull) +#define CVMX_AGL_GMX_TX_JAM \ + CVMX_ADD_IO_SEG(0x00011800E0000490ull) +#define CVMX_AGL_GMX_TX_LFSR \ + CVMX_ADD_IO_SEG(0x00011800E00004F8ull) +#define CVMX_AGL_GMX_TX_OVR_BP \ + CVMX_ADD_IO_SEG(0x00011800E00004C8ull) +#define CVMX_AGL_GMX_TX_PAUSE_PKT_DMAC \ + CVMX_ADD_IO_SEG(0x00011800E00004A0ull) +#define CVMX_AGL_GMX_TX_PAUSE_PKT_TYPE \ + CVMX_ADD_IO_SEG(0x00011800E00004A8ull) union cvmx_agl_gmx_bad_reg { uint64_t u64; struct cvmx_agl_gmx_bad_reg_s { - uint64_t reserved_38_63:26; - uint64_t txpsh1:1; - uint64_t txpop1:1; - uint64_t ovrflw1:1; - uint64_t txpsh:1; - uint64_t txpop:1; - uint64_t ovrflw:1; - uint64_t reserved_27_31:5; - uint64_t statovr:1; - uint64_t reserved_24_25:2; - uint64_t loststat:2; - uint64_t reserved_4_21:18; - uint64_t out_ovr:2; - uint64_t reserved_0_1:2; - } s; - struct cvmx_agl_gmx_bad_reg_cn52xx { uint64_t reserved_38_63:26; uint64_t txpsh1:1; uint64_t txpop1:1; @@ -136,8 +188,9 @@ union cvmx_agl_gmx_bad_reg { uint64_t reserved_4_21:18; uint64_t out_ovr:2; uint64_t reserved_0_1:2; - } cn52xx; - struct cvmx_agl_gmx_bad_reg_cn52xx cn52xxp1; + } s; + struct cvmx_agl_gmx_bad_reg_s cn52xx; + struct cvmx_agl_gmx_bad_reg_s cn52xxp1; struct cvmx_agl_gmx_bad_reg_cn56xx { uint64_t reserved_35_63:29; uint64_t txpsh:1; @@ -152,25 +205,18 @@ union cvmx_agl_gmx_bad_reg { uint64_t reserved_0_1:2; } cn56xx; struct cvmx_agl_gmx_bad_reg_cn56xx cn56xxp1; - struct cvmx_agl_gmx_bad_reg_s cn63xx; - struct cvmx_agl_gmx_bad_reg_s cn63xxp1; }; union cvmx_agl_gmx_bist { uint64_t u64; struct cvmx_agl_gmx_bist_s { - uint64_t reserved_25_63:39; - uint64_t status:25; - } s; - struct cvmx_agl_gmx_bist_cn52xx { uint64_t reserved_10_63:54; uint64_t status:10; - } cn52xx; - struct cvmx_agl_gmx_bist_cn52xx cn52xxp1; - struct cvmx_agl_gmx_bist_cn52xx cn56xx; - struct cvmx_agl_gmx_bist_cn52xx cn56xxp1; - struct cvmx_agl_gmx_bist_s cn63xx; - struct cvmx_agl_gmx_bist_s cn63xxp1; + } s; + struct cvmx_agl_gmx_bist_s cn52xx; + struct cvmx_agl_gmx_bist_s cn52xxp1; + struct cvmx_agl_gmx_bist_s cn56xx; + struct cvmx_agl_gmx_bist_s cn56xxp1; }; union cvmx_agl_gmx_drv_ctl { @@ -218,21 +264,6 @@ union cvmx_agl_gmx_inf_mode { union cvmx_agl_gmx_prtx_cfg { uint64_t u64; struct cvmx_agl_gmx_prtx_cfg_s { - uint64_t reserved_14_63:50; - uint64_t tx_idle:1; - uint64_t rx_idle:1; - uint64_t reserved_9_11:3; - uint64_t speed_msb:1; - uint64_t reserved_7_7:1; - uint64_t burst:1; - uint64_t tx_en:1; - uint64_t rx_en:1; - uint64_t slottime:1; - uint64_t duplex:1; - uint64_t speed:1; - uint64_t en:1; - } s; - struct cvmx_agl_gmx_prtx_cfg_cn52xx { uint64_t reserved_6_63:58; uint64_t tx_en:1; uint64_t rx_en:1; @@ -240,12 +271,11 @@ union cvmx_agl_gmx_prtx_cfg { uint64_t duplex:1; uint64_t speed:1; uint64_t en:1; - } cn52xx; - struct cvmx_agl_gmx_prtx_cfg_cn52xx cn52xxp1; - struct cvmx_agl_gmx_prtx_cfg_cn52xx cn56xx; - struct cvmx_agl_gmx_prtx_cfg_cn52xx cn56xxp1; - struct cvmx_agl_gmx_prtx_cfg_s cn63xx; - struct cvmx_agl_gmx_prtx_cfg_s cn63xxp1; + } s; + struct cvmx_agl_gmx_prtx_cfg_s cn52xx; + struct cvmx_agl_gmx_prtx_cfg_s cn52xxp1; + struct cvmx_agl_gmx_prtx_cfg_s cn56xx; + struct cvmx_agl_gmx_prtx_cfg_s cn56xxp1; }; union cvmx_agl_gmx_rxx_adr_cam0 { @@ -257,8 +287,6 @@ union cvmx_agl_gmx_rxx_adr_cam0 { struct cvmx_agl_gmx_rxx_adr_cam0_s cn52xxp1; struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xx; struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xxp1; - struct cvmx_agl_gmx_rxx_adr_cam0_s cn63xx; - struct cvmx_agl_gmx_rxx_adr_cam0_s cn63xxp1; }; union cvmx_agl_gmx_rxx_adr_cam1 { @@ -270,8 +298,6 @@ union cvmx_agl_gmx_rxx_adr_cam1 { struct cvmx_agl_gmx_rxx_adr_cam1_s cn52xxp1; struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xx; struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xxp1; - struct cvmx_agl_gmx_rxx_adr_cam1_s cn63xx; - struct cvmx_agl_gmx_rxx_adr_cam1_s cn63xxp1; }; union cvmx_agl_gmx_rxx_adr_cam2 { @@ -283,8 +309,6 @@ union cvmx_agl_gmx_rxx_adr_cam2 { struct cvmx_agl_gmx_rxx_adr_cam2_s cn52xxp1; struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xx; struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xxp1; - struct cvmx_agl_gmx_rxx_adr_cam2_s cn63xx; - struct cvmx_agl_gmx_rxx_adr_cam2_s cn63xxp1; }; union cvmx_agl_gmx_rxx_adr_cam3 { @@ -296,8 +320,6 @@ union cvmx_agl_gmx_rxx_adr_cam3 { struct cvmx_agl_gmx_rxx_adr_cam3_s cn52xxp1; struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xx; struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xxp1; - struct cvmx_agl_gmx_rxx_adr_cam3_s cn63xx; - struct cvmx_agl_gmx_rxx_adr_cam3_s cn63xxp1; }; union cvmx_agl_gmx_rxx_adr_cam4 { @@ -309,8 +331,6 @@ union cvmx_agl_gmx_rxx_adr_cam4 { struct cvmx_agl_gmx_rxx_adr_cam4_s cn52xxp1; struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xx; struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xxp1; - struct cvmx_agl_gmx_rxx_adr_cam4_s cn63xx; - struct cvmx_agl_gmx_rxx_adr_cam4_s cn63xxp1; }; union cvmx_agl_gmx_rxx_adr_cam5 { @@ -322,8 +342,6 @@ union cvmx_agl_gmx_rxx_adr_cam5 { struct cvmx_agl_gmx_rxx_adr_cam5_s cn52xxp1; struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xx; struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xxp1; - struct cvmx_agl_gmx_rxx_adr_cam5_s cn63xx; - struct cvmx_agl_gmx_rxx_adr_cam5_s cn63xxp1; }; union cvmx_agl_gmx_rxx_adr_cam_en { @@ -336,8 +354,6 @@ union cvmx_agl_gmx_rxx_adr_cam_en { struct cvmx_agl_gmx_rxx_adr_cam_en_s cn52xxp1; struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xx; struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xxp1; - struct cvmx_agl_gmx_rxx_adr_cam_en_s cn63xx; - struct cvmx_agl_gmx_rxx_adr_cam_en_s cn63xxp1; }; union cvmx_agl_gmx_rxx_adr_ctl { @@ -352,8 +368,6 @@ union cvmx_agl_gmx_rxx_adr_ctl { struct cvmx_agl_gmx_rxx_adr_ctl_s cn52xxp1; struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xx; struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xxp1; - struct cvmx_agl_gmx_rxx_adr_ctl_s cn63xx; - struct cvmx_agl_gmx_rxx_adr_ctl_s cn63xxp1; }; union cvmx_agl_gmx_rxx_decision { @@ -366,26 +380,11 @@ union cvmx_agl_gmx_rxx_decision { struct cvmx_agl_gmx_rxx_decision_s cn52xxp1; struct cvmx_agl_gmx_rxx_decision_s cn56xx; struct cvmx_agl_gmx_rxx_decision_s cn56xxp1; - struct cvmx_agl_gmx_rxx_decision_s cn63xx; - struct cvmx_agl_gmx_rxx_decision_s cn63xxp1; }; union cvmx_agl_gmx_rxx_frm_chk { uint64_t u64; struct cvmx_agl_gmx_rxx_frm_chk_s { - uint64_t reserved_10_63:54; - uint64_t niberr:1; - uint64_t skperr:1; - uint64_t rcverr:1; - uint64_t lenerr:1; - uint64_t alnerr:1; - uint64_t fcserr:1; - uint64_t jabber:1; - uint64_t maxerr:1; - uint64_t carext:1; - uint64_t minerr:1; - } s; - struct cvmx_agl_gmx_rxx_frm_chk_cn52xx { uint64_t reserved_9_63:55; uint64_t skperr:1; uint64_t rcverr:1; @@ -396,33 +395,16 @@ union cvmx_agl_gmx_rxx_frm_chk { uint64_t maxerr:1; uint64_t reserved_1_1:1; uint64_t minerr:1; - } cn52xx; - struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn52xxp1; - struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn56xx; - struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn56xxp1; - struct cvmx_agl_gmx_rxx_frm_chk_s cn63xx; - struct cvmx_agl_gmx_rxx_frm_chk_s cn63xxp1; + } s; + struct cvmx_agl_gmx_rxx_frm_chk_s cn52xx; + struct cvmx_agl_gmx_rxx_frm_chk_s cn52xxp1; + struct cvmx_agl_gmx_rxx_frm_chk_s cn56xx; + struct cvmx_agl_gmx_rxx_frm_chk_s cn56xxp1; }; union cvmx_agl_gmx_rxx_frm_ctl { uint64_t u64; struct cvmx_agl_gmx_rxx_frm_ctl_s { - uint64_t reserved_13_63:51; - uint64_t ptp_mode:1; - uint64_t reserved_11_11:1; - uint64_t null_dis:1; - uint64_t pre_align:1; - uint64_t pad_len:1; - uint64_t vlan_len:1; - uint64_t pre_free:1; - uint64_t ctl_smac:1; - uint64_t ctl_mcst:1; - uint64_t ctl_bck:1; - uint64_t ctl_drp:1; - uint64_t pre_strp:1; - uint64_t pre_chk:1; - } s; - struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx { uint64_t reserved_10_63:54; uint64_t pre_align:1; uint64_t pad_len:1; @@ -434,12 +416,11 @@ union cvmx_agl_gmx_rxx_frm_ctl { uint64_t ctl_drp:1; uint64_t pre_strp:1; uint64_t pre_chk:1; - } cn52xx; - struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn52xxp1; - struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn56xx; - struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn56xxp1; - struct cvmx_agl_gmx_rxx_frm_ctl_s cn63xx; - struct cvmx_agl_gmx_rxx_frm_ctl_s cn63xxp1; + } s; + struct cvmx_agl_gmx_rxx_frm_ctl_s cn52xx; + struct cvmx_agl_gmx_rxx_frm_ctl_s cn52xxp1; + struct cvmx_agl_gmx_rxx_frm_ctl_s cn56xx; + struct cvmx_agl_gmx_rxx_frm_ctl_s cn56xxp1; }; union cvmx_agl_gmx_rxx_frm_max { @@ -452,8 +433,6 @@ union cvmx_agl_gmx_rxx_frm_max { struct cvmx_agl_gmx_rxx_frm_max_s cn52xxp1; struct cvmx_agl_gmx_rxx_frm_max_s cn56xx; struct cvmx_agl_gmx_rxx_frm_max_s cn56xxp1; - struct cvmx_agl_gmx_rxx_frm_max_s cn63xx; - struct cvmx_agl_gmx_rxx_frm_max_s cn63xxp1; }; union cvmx_agl_gmx_rxx_frm_min { @@ -466,8 +445,6 @@ union cvmx_agl_gmx_rxx_frm_min { struct cvmx_agl_gmx_rxx_frm_min_s cn52xxp1; struct cvmx_agl_gmx_rxx_frm_min_s cn56xx; struct cvmx_agl_gmx_rxx_frm_min_s cn56xxp1; - struct cvmx_agl_gmx_rxx_frm_min_s cn63xx; - struct cvmx_agl_gmx_rxx_frm_min_s cn63xxp1; }; union cvmx_agl_gmx_rxx_ifg { @@ -480,36 +457,11 @@ union cvmx_agl_gmx_rxx_ifg { struct cvmx_agl_gmx_rxx_ifg_s cn52xxp1; struct cvmx_agl_gmx_rxx_ifg_s cn56xx; struct cvmx_agl_gmx_rxx_ifg_s cn56xxp1; - struct cvmx_agl_gmx_rxx_ifg_s cn63xx; - struct cvmx_agl_gmx_rxx_ifg_s cn63xxp1; }; union cvmx_agl_gmx_rxx_int_en { uint64_t u64; struct cvmx_agl_gmx_rxx_int_en_s { - uint64_t reserved_20_63:44; - uint64_t pause_drp:1; - uint64_t phy_dupx:1; - uint64_t phy_spd:1; - uint64_t phy_link:1; - uint64_t ifgerr:1; - uint64_t coldet:1; - uint64_t falerr:1; - uint64_t rsverr:1; - uint64_t pcterr:1; - uint64_t ovrerr:1; - uint64_t niberr:1; - uint64_t skperr:1; - uint64_t rcverr:1; - uint64_t lenerr:1; - uint64_t alnerr:1; - uint64_t fcserr:1; - uint64_t jabber:1; - uint64_t maxerr:1; - uint64_t carext:1; - uint64_t minerr:1; - } s; - struct cvmx_agl_gmx_rxx_int_en_cn52xx { uint64_t reserved_20_63:44; uint64_t pause_drp:1; uint64_t reserved_16_18:3; @@ -529,40 +481,16 @@ union cvmx_agl_gmx_rxx_int_en { uint64_t maxerr:1; uint64_t reserved_1_1:1; uint64_t minerr:1; - } cn52xx; - struct cvmx_agl_gmx_rxx_int_en_cn52xx cn52xxp1; - struct cvmx_agl_gmx_rxx_int_en_cn52xx cn56xx; - struct cvmx_agl_gmx_rxx_int_en_cn52xx cn56xxp1; - struct cvmx_agl_gmx_rxx_int_en_s cn63xx; - struct cvmx_agl_gmx_rxx_int_en_s cn63xxp1; + } s; + struct cvmx_agl_gmx_rxx_int_en_s cn52xx; + struct cvmx_agl_gmx_rxx_int_en_s cn52xxp1; + struct cvmx_agl_gmx_rxx_int_en_s cn56xx; + struct cvmx_agl_gmx_rxx_int_en_s cn56xxp1; }; union cvmx_agl_gmx_rxx_int_reg { uint64_t u64; struct cvmx_agl_gmx_rxx_int_reg_s { - uint64_t reserved_20_63:44; - uint64_t pause_drp:1; - uint64_t phy_dupx:1; - uint64_t phy_spd:1; - uint64_t phy_link:1; - uint64_t ifgerr:1; - uint64_t coldet:1; - uint64_t falerr:1; - uint64_t rsverr:1; - uint64_t pcterr:1; - uint64_t ovrerr:1; - uint64_t niberr:1; - uint64_t skperr:1; - uint64_t rcverr:1; - uint64_t lenerr:1; - uint64_t alnerr:1; - uint64_t fcserr:1; - uint64_t jabber:1; - uint64_t maxerr:1; - uint64_t carext:1; - uint64_t minerr:1; - } s; - struct cvmx_agl_gmx_rxx_int_reg_cn52xx { uint64_t reserved_20_63:44; uint64_t pause_drp:1; uint64_t reserved_16_18:3; @@ -582,12 +510,11 @@ union cvmx_agl_gmx_rxx_int_reg { uint64_t maxerr:1; uint64_t reserved_1_1:1; uint64_t minerr:1; - } cn52xx; - struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn52xxp1; - struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn56xx; - struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn56xxp1; - struct cvmx_agl_gmx_rxx_int_reg_s cn63xx; - struct cvmx_agl_gmx_rxx_int_reg_s cn63xxp1; + } s; + struct cvmx_agl_gmx_rxx_int_reg_s cn52xx; + struct cvmx_agl_gmx_rxx_int_reg_s cn52xxp1; + struct cvmx_agl_gmx_rxx_int_reg_s cn56xx; + struct cvmx_agl_gmx_rxx_int_reg_s cn56xxp1; }; union cvmx_agl_gmx_rxx_jabber { @@ -600,8 +527,6 @@ union cvmx_agl_gmx_rxx_jabber { struct cvmx_agl_gmx_rxx_jabber_s cn52xxp1; struct cvmx_agl_gmx_rxx_jabber_s cn56xx; struct cvmx_agl_gmx_rxx_jabber_s cn56xxp1; - struct cvmx_agl_gmx_rxx_jabber_s cn63xx; - struct cvmx_agl_gmx_rxx_jabber_s cn63xxp1; }; union cvmx_agl_gmx_rxx_pause_drop_time { @@ -614,20 +539,6 @@ union cvmx_agl_gmx_rxx_pause_drop_time { struct cvmx_agl_gmx_rxx_pause_drop_time_s cn52xxp1; struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xx; struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xxp1; - struct cvmx_agl_gmx_rxx_pause_drop_time_s cn63xx; - struct cvmx_agl_gmx_rxx_pause_drop_time_s cn63xxp1; -}; - -union cvmx_agl_gmx_rxx_rx_inbnd { - uint64_t u64; - struct cvmx_agl_gmx_rxx_rx_inbnd_s { - uint64_t reserved_4_63:60; - uint64_t duplex:1; - uint64_t speed:2; - uint64_t status:1; - } s; - struct cvmx_agl_gmx_rxx_rx_inbnd_s cn63xx; - struct cvmx_agl_gmx_rxx_rx_inbnd_s cn63xxp1; }; union cvmx_agl_gmx_rxx_stats_ctl { @@ -640,8 +551,6 @@ union cvmx_agl_gmx_rxx_stats_ctl { struct cvmx_agl_gmx_rxx_stats_ctl_s cn52xxp1; struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xx; struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xxp1; - struct cvmx_agl_gmx_rxx_stats_ctl_s cn63xx; - struct cvmx_agl_gmx_rxx_stats_ctl_s cn63xxp1; }; union cvmx_agl_gmx_rxx_stats_octs { @@ -654,8 +563,6 @@ union cvmx_agl_gmx_rxx_stats_octs { struct cvmx_agl_gmx_rxx_stats_octs_s cn52xxp1; struct cvmx_agl_gmx_rxx_stats_octs_s cn56xx; struct cvmx_agl_gmx_rxx_stats_octs_s cn56xxp1; - struct cvmx_agl_gmx_rxx_stats_octs_s cn63xx; - struct cvmx_agl_gmx_rxx_stats_octs_s cn63xxp1; }; union cvmx_agl_gmx_rxx_stats_octs_ctl { @@ -668,8 +575,6 @@ union cvmx_agl_gmx_rxx_stats_octs_ctl { struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn52xxp1; struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xx; struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xxp1; - struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn63xx; - struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn63xxp1; }; union cvmx_agl_gmx_rxx_stats_octs_dmac { @@ -682,8 +587,6 @@ union cvmx_agl_gmx_rxx_stats_octs_dmac { struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn52xxp1; struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xx; struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xxp1; - struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn63xx; - struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn63xxp1; }; union cvmx_agl_gmx_rxx_stats_octs_drp { @@ -696,8 +599,6 @@ union cvmx_agl_gmx_rxx_stats_octs_drp { struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn52xxp1; struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xx; struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xxp1; - struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn63xx; - struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn63xxp1; }; union cvmx_agl_gmx_rxx_stats_pkts { @@ -710,8 +611,6 @@ union cvmx_agl_gmx_rxx_stats_pkts { struct cvmx_agl_gmx_rxx_stats_pkts_s cn52xxp1; struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xx; struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xxp1; - struct cvmx_agl_gmx_rxx_stats_pkts_s cn63xx; - struct cvmx_agl_gmx_rxx_stats_pkts_s cn63xxp1; }; union cvmx_agl_gmx_rxx_stats_pkts_bad { @@ -724,8 +623,6 @@ union cvmx_agl_gmx_rxx_stats_pkts_bad { struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn52xxp1; struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xx; struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xxp1; - struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn63xx; - struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn63xxp1; }; union cvmx_agl_gmx_rxx_stats_pkts_ctl { @@ -738,8 +635,6 @@ union cvmx_agl_gmx_rxx_stats_pkts_ctl { struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn52xxp1; struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xx; struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xxp1; - struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn63xx; - struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn63xxp1; }; union cvmx_agl_gmx_rxx_stats_pkts_dmac { @@ -752,8 +647,6 @@ union cvmx_agl_gmx_rxx_stats_pkts_dmac { struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn52xxp1; struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xx; struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xxp1; - struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn63xx; - struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn63xxp1; }; union cvmx_agl_gmx_rxx_stats_pkts_drp { @@ -766,8 +659,6 @@ union cvmx_agl_gmx_rxx_stats_pkts_drp { struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn52xxp1; struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xx; struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xxp1; - struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn63xx; - struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn63xxp1; }; union cvmx_agl_gmx_rxx_udd_skp { @@ -782,8 +673,6 @@ union cvmx_agl_gmx_rxx_udd_skp { struct cvmx_agl_gmx_rxx_udd_skp_s cn52xxp1; struct cvmx_agl_gmx_rxx_udd_skp_s cn56xx; struct cvmx_agl_gmx_rxx_udd_skp_s cn56xxp1; - struct cvmx_agl_gmx_rxx_udd_skp_s cn63xx; - struct cvmx_agl_gmx_rxx_udd_skp_s cn63xxp1; }; union cvmx_agl_gmx_rx_bp_dropx { @@ -796,8 +685,6 @@ union cvmx_agl_gmx_rx_bp_dropx { struct cvmx_agl_gmx_rx_bp_dropx_s cn52xxp1; struct cvmx_agl_gmx_rx_bp_dropx_s cn56xx; struct cvmx_agl_gmx_rx_bp_dropx_s cn56xxp1; - struct cvmx_agl_gmx_rx_bp_dropx_s cn63xx; - struct cvmx_agl_gmx_rx_bp_dropx_s cn63xxp1; }; union cvmx_agl_gmx_rx_bp_offx { @@ -810,8 +697,6 @@ union cvmx_agl_gmx_rx_bp_offx { struct cvmx_agl_gmx_rx_bp_offx_s cn52xxp1; struct cvmx_agl_gmx_rx_bp_offx_s cn56xx; struct cvmx_agl_gmx_rx_bp_offx_s cn56xxp1; - struct cvmx_agl_gmx_rx_bp_offx_s cn63xx; - struct cvmx_agl_gmx_rx_bp_offx_s cn63xxp1; }; union cvmx_agl_gmx_rx_bp_onx { @@ -824,8 +709,6 @@ union cvmx_agl_gmx_rx_bp_onx { struct cvmx_agl_gmx_rx_bp_onx_s cn52xxp1; struct cvmx_agl_gmx_rx_bp_onx_s cn56xx; struct cvmx_agl_gmx_rx_bp_onx_s cn56xxp1; - struct cvmx_agl_gmx_rx_bp_onx_s cn63xx; - struct cvmx_agl_gmx_rx_bp_onx_s cn63xxp1; }; union cvmx_agl_gmx_rx_prt_info { @@ -845,8 +728,6 @@ union cvmx_agl_gmx_rx_prt_info { uint64_t commit:1; } cn56xx; struct cvmx_agl_gmx_rx_prt_info_cn56xx cn56xxp1; - struct cvmx_agl_gmx_rx_prt_info_s cn63xx; - struct cvmx_agl_gmx_rx_prt_info_s cn63xxp1; }; union cvmx_agl_gmx_rx_tx_status { @@ -866,8 +747,6 @@ union cvmx_agl_gmx_rx_tx_status { uint64_t rx:1; } cn56xx; struct cvmx_agl_gmx_rx_tx_status_cn56xx cn56xxp1; - struct cvmx_agl_gmx_rx_tx_status_s cn63xx; - struct cvmx_agl_gmx_rx_tx_status_s cn63xxp1; }; union cvmx_agl_gmx_smacx { @@ -880,8 +759,6 @@ union cvmx_agl_gmx_smacx { struct cvmx_agl_gmx_smacx_s cn52xxp1; struct cvmx_agl_gmx_smacx_s cn56xx; struct cvmx_agl_gmx_smacx_s cn56xxp1; - struct cvmx_agl_gmx_smacx_s cn63xx; - struct cvmx_agl_gmx_smacx_s cn63xxp1; }; union cvmx_agl_gmx_stat_bp { @@ -895,8 +772,6 @@ union cvmx_agl_gmx_stat_bp { struct cvmx_agl_gmx_stat_bp_s cn52xxp1; struct cvmx_agl_gmx_stat_bp_s cn56xx; struct cvmx_agl_gmx_stat_bp_s cn56xxp1; - struct cvmx_agl_gmx_stat_bp_s cn63xx; - struct cvmx_agl_gmx_stat_bp_s cn63xxp1; }; union cvmx_agl_gmx_txx_append { @@ -912,18 +787,6 @@ union cvmx_agl_gmx_txx_append { struct cvmx_agl_gmx_txx_append_s cn52xxp1; struct cvmx_agl_gmx_txx_append_s cn56xx; struct cvmx_agl_gmx_txx_append_s cn56xxp1; - struct cvmx_agl_gmx_txx_append_s cn63xx; - struct cvmx_agl_gmx_txx_append_s cn63xxp1; -}; - -union cvmx_agl_gmx_txx_clk { - uint64_t u64; - struct cvmx_agl_gmx_txx_clk_s { - uint64_t reserved_6_63:58; - uint64_t clk_cnt:6; - } s; - struct cvmx_agl_gmx_txx_clk_s cn63xx; - struct cvmx_agl_gmx_txx_clk_s cn63xxp1; }; union cvmx_agl_gmx_txx_ctl { @@ -937,8 +800,6 @@ union cvmx_agl_gmx_txx_ctl { struct cvmx_agl_gmx_txx_ctl_s cn52xxp1; struct cvmx_agl_gmx_txx_ctl_s cn56xx; struct cvmx_agl_gmx_txx_ctl_s cn56xxp1; - struct cvmx_agl_gmx_txx_ctl_s cn63xx; - struct cvmx_agl_gmx_txx_ctl_s cn63xxp1; }; union cvmx_agl_gmx_txx_min_pkt { @@ -951,8 +812,6 @@ union cvmx_agl_gmx_txx_min_pkt { struct cvmx_agl_gmx_txx_min_pkt_s cn52xxp1; struct cvmx_agl_gmx_txx_min_pkt_s cn56xx; struct cvmx_agl_gmx_txx_min_pkt_s cn56xxp1; - struct cvmx_agl_gmx_txx_min_pkt_s cn63xx; - struct cvmx_agl_gmx_txx_min_pkt_s cn63xxp1; }; union cvmx_agl_gmx_txx_pause_pkt_interval { @@ -965,8 +824,6 @@ union cvmx_agl_gmx_txx_pause_pkt_interval { struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn52xxp1; struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xx; struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xxp1; - struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn63xx; - struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn63xxp1; }; union cvmx_agl_gmx_txx_pause_pkt_time { @@ -979,8 +836,6 @@ union cvmx_agl_gmx_txx_pause_pkt_time { struct cvmx_agl_gmx_txx_pause_pkt_time_s cn52xxp1; struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xx; struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xxp1; - struct cvmx_agl_gmx_txx_pause_pkt_time_s cn63xx; - struct cvmx_agl_gmx_txx_pause_pkt_time_s cn63xxp1; }; union cvmx_agl_gmx_txx_pause_togo { @@ -993,8 +848,6 @@ union cvmx_agl_gmx_txx_pause_togo { struct cvmx_agl_gmx_txx_pause_togo_s cn52xxp1; struct cvmx_agl_gmx_txx_pause_togo_s cn56xx; struct cvmx_agl_gmx_txx_pause_togo_s cn56xxp1; - struct cvmx_agl_gmx_txx_pause_togo_s cn63xx; - struct cvmx_agl_gmx_txx_pause_togo_s cn63xxp1; }; union cvmx_agl_gmx_txx_pause_zero { @@ -1007,8 +860,6 @@ union cvmx_agl_gmx_txx_pause_zero { struct cvmx_agl_gmx_txx_pause_zero_s cn52xxp1; struct cvmx_agl_gmx_txx_pause_zero_s cn56xx; struct cvmx_agl_gmx_txx_pause_zero_s cn56xxp1; - struct cvmx_agl_gmx_txx_pause_zero_s cn63xx; - struct cvmx_agl_gmx_txx_pause_zero_s cn63xxp1; }; union cvmx_agl_gmx_txx_soft_pause { @@ -1021,8 +872,6 @@ union cvmx_agl_gmx_txx_soft_pause { struct cvmx_agl_gmx_txx_soft_pause_s cn52xxp1; struct cvmx_agl_gmx_txx_soft_pause_s cn56xx; struct cvmx_agl_gmx_txx_soft_pause_s cn56xxp1; - struct cvmx_agl_gmx_txx_soft_pause_s cn63xx; - struct cvmx_agl_gmx_txx_soft_pause_s cn63xxp1; }; union cvmx_agl_gmx_txx_stat0 { @@ -1035,8 +884,6 @@ union cvmx_agl_gmx_txx_stat0 { struct cvmx_agl_gmx_txx_stat0_s cn52xxp1; struct cvmx_agl_gmx_txx_stat0_s cn56xx; struct cvmx_agl_gmx_txx_stat0_s cn56xxp1; - struct cvmx_agl_gmx_txx_stat0_s cn63xx; - struct cvmx_agl_gmx_txx_stat0_s cn63xxp1; }; union cvmx_agl_gmx_txx_stat1 { @@ -1049,8 +896,6 @@ union cvmx_agl_gmx_txx_stat1 { struct cvmx_agl_gmx_txx_stat1_s cn52xxp1; struct cvmx_agl_gmx_txx_stat1_s cn56xx; struct cvmx_agl_gmx_txx_stat1_s cn56xxp1; - struct cvmx_agl_gmx_txx_stat1_s cn63xx; - struct cvmx_agl_gmx_txx_stat1_s cn63xxp1; }; union cvmx_agl_gmx_txx_stat2 { @@ -1063,8 +908,6 @@ union cvmx_agl_gmx_txx_stat2 { struct cvmx_agl_gmx_txx_stat2_s cn52xxp1; struct cvmx_agl_gmx_txx_stat2_s cn56xx; struct cvmx_agl_gmx_txx_stat2_s cn56xxp1; - struct cvmx_agl_gmx_txx_stat2_s cn63xx; - struct cvmx_agl_gmx_txx_stat2_s cn63xxp1; }; union cvmx_agl_gmx_txx_stat3 { @@ -1077,8 +920,6 @@ union cvmx_agl_gmx_txx_stat3 { struct cvmx_agl_gmx_txx_stat3_s cn52xxp1; struct cvmx_agl_gmx_txx_stat3_s cn56xx; struct cvmx_agl_gmx_txx_stat3_s cn56xxp1; - struct cvmx_agl_gmx_txx_stat3_s cn63xx; - struct cvmx_agl_gmx_txx_stat3_s cn63xxp1; }; union cvmx_agl_gmx_txx_stat4 { @@ -1091,8 +932,6 @@ union cvmx_agl_gmx_txx_stat4 { struct cvmx_agl_gmx_txx_stat4_s cn52xxp1; struct cvmx_agl_gmx_txx_stat4_s cn56xx; struct cvmx_agl_gmx_txx_stat4_s cn56xxp1; - struct cvmx_agl_gmx_txx_stat4_s cn63xx; - struct cvmx_agl_gmx_txx_stat4_s cn63xxp1; }; union cvmx_agl_gmx_txx_stat5 { @@ -1105,8 +944,6 @@ union cvmx_agl_gmx_txx_stat5 { struct cvmx_agl_gmx_txx_stat5_s cn52xxp1; struct cvmx_agl_gmx_txx_stat5_s cn56xx; struct cvmx_agl_gmx_txx_stat5_s cn56xxp1; - struct cvmx_agl_gmx_txx_stat5_s cn63xx; - struct cvmx_agl_gmx_txx_stat5_s cn63xxp1; }; union cvmx_agl_gmx_txx_stat6 { @@ -1119,8 +956,6 @@ union cvmx_agl_gmx_txx_stat6 { struct cvmx_agl_gmx_txx_stat6_s cn52xxp1; struct cvmx_agl_gmx_txx_stat6_s cn56xx; struct cvmx_agl_gmx_txx_stat6_s cn56xxp1; - struct cvmx_agl_gmx_txx_stat6_s cn63xx; - struct cvmx_agl_gmx_txx_stat6_s cn63xxp1; }; union cvmx_agl_gmx_txx_stat7 { @@ -1133,8 +968,6 @@ union cvmx_agl_gmx_txx_stat7 { struct cvmx_agl_gmx_txx_stat7_s cn52xxp1; struct cvmx_agl_gmx_txx_stat7_s cn56xx; struct cvmx_agl_gmx_txx_stat7_s cn56xxp1; - struct cvmx_agl_gmx_txx_stat7_s cn63xx; - struct cvmx_agl_gmx_txx_stat7_s cn63xxp1; }; union cvmx_agl_gmx_txx_stat8 { @@ -1147,8 +980,6 @@ union cvmx_agl_gmx_txx_stat8 { struct cvmx_agl_gmx_txx_stat8_s cn52xxp1; struct cvmx_agl_gmx_txx_stat8_s cn56xx; struct cvmx_agl_gmx_txx_stat8_s cn56xxp1; - struct cvmx_agl_gmx_txx_stat8_s cn63xx; - struct cvmx_agl_gmx_txx_stat8_s cn63xxp1; }; union cvmx_agl_gmx_txx_stat9 { @@ -1161,8 +992,6 @@ union cvmx_agl_gmx_txx_stat9 { struct cvmx_agl_gmx_txx_stat9_s cn52xxp1; struct cvmx_agl_gmx_txx_stat9_s cn56xx; struct cvmx_agl_gmx_txx_stat9_s cn56xxp1; - struct cvmx_agl_gmx_txx_stat9_s cn63xx; - struct cvmx_agl_gmx_txx_stat9_s cn63xxp1; }; union cvmx_agl_gmx_txx_stats_ctl { @@ -1175,8 +1004,6 @@ union cvmx_agl_gmx_txx_stats_ctl { struct cvmx_agl_gmx_txx_stats_ctl_s cn52xxp1; struct cvmx_agl_gmx_txx_stats_ctl_s cn56xx; struct cvmx_agl_gmx_txx_stats_ctl_s cn56xxp1; - struct cvmx_agl_gmx_txx_stats_ctl_s cn63xx; - struct cvmx_agl_gmx_txx_stats_ctl_s cn63xxp1; }; union cvmx_agl_gmx_txx_thresh { @@ -1189,8 +1016,6 @@ union cvmx_agl_gmx_txx_thresh { struct cvmx_agl_gmx_txx_thresh_s cn52xxp1; struct cvmx_agl_gmx_txx_thresh_s cn56xx; struct cvmx_agl_gmx_txx_thresh_s cn56xxp1; - struct cvmx_agl_gmx_txx_thresh_s cn63xx; - struct cvmx_agl_gmx_txx_thresh_s cn63xxp1; }; union cvmx_agl_gmx_tx_bp { @@ -1206,8 +1031,6 @@ union cvmx_agl_gmx_tx_bp { uint64_t bp:1; } cn56xx; struct cvmx_agl_gmx_tx_bp_cn56xx cn56xxp1; - struct cvmx_agl_gmx_tx_bp_s cn63xx; - struct cvmx_agl_gmx_tx_bp_s cn63xxp1; }; union cvmx_agl_gmx_tx_col_attempt { @@ -1220,8 +1043,6 @@ union cvmx_agl_gmx_tx_col_attempt { struct cvmx_agl_gmx_tx_col_attempt_s cn52xxp1; struct cvmx_agl_gmx_tx_col_attempt_s cn56xx; struct cvmx_agl_gmx_tx_col_attempt_s cn56xxp1; - struct cvmx_agl_gmx_tx_col_attempt_s cn63xx; - struct cvmx_agl_gmx_tx_col_attempt_s cn63xxp1; }; union cvmx_agl_gmx_tx_ifg { @@ -1235,27 +1056,11 @@ union cvmx_agl_gmx_tx_ifg { struct cvmx_agl_gmx_tx_ifg_s cn52xxp1; struct cvmx_agl_gmx_tx_ifg_s cn56xx; struct cvmx_agl_gmx_tx_ifg_s cn56xxp1; - struct cvmx_agl_gmx_tx_ifg_s cn63xx; - struct cvmx_agl_gmx_tx_ifg_s cn63xxp1; }; union cvmx_agl_gmx_tx_int_en { uint64_t u64; struct cvmx_agl_gmx_tx_int_en_s { - uint64_t reserved_22_63:42; - uint64_t ptp_lost:2; - uint64_t reserved_18_19:2; - uint64_t late_col:2; - uint64_t reserved_14_15:2; - uint64_t xsdef:2; - uint64_t reserved_10_11:2; - uint64_t xscol:2; - uint64_t reserved_4_7:4; - uint64_t undflw:2; - uint64_t reserved_1_1:1; - uint64_t pko_nxa:1; - } s; - struct cvmx_agl_gmx_tx_int_en_cn52xx { uint64_t reserved_18_63:46; uint64_t late_col:2; uint64_t reserved_14_15:2; @@ -1266,8 +1071,9 @@ union cvmx_agl_gmx_tx_int_en { uint64_t undflw:2; uint64_t reserved_1_1:1; uint64_t pko_nxa:1; - } cn52xx; - struct cvmx_agl_gmx_tx_int_en_cn52xx cn52xxp1; + } s; + struct cvmx_agl_gmx_tx_int_en_s cn52xx; + struct cvmx_agl_gmx_tx_int_en_s cn52xxp1; struct cvmx_agl_gmx_tx_int_en_cn56xx { uint64_t reserved_17_63:47; uint64_t late_col:1; @@ -1281,27 +1087,11 @@ union cvmx_agl_gmx_tx_int_en { uint64_t pko_nxa:1; } cn56xx; struct cvmx_agl_gmx_tx_int_en_cn56xx cn56xxp1; - struct cvmx_agl_gmx_tx_int_en_s cn63xx; - struct cvmx_agl_gmx_tx_int_en_s cn63xxp1; }; union cvmx_agl_gmx_tx_int_reg { uint64_t u64; struct cvmx_agl_gmx_tx_int_reg_s { - uint64_t reserved_22_63:42; - uint64_t ptp_lost:2; - uint64_t reserved_18_19:2; - uint64_t late_col:2; - uint64_t reserved_14_15:2; - uint64_t xsdef:2; - uint64_t reserved_10_11:2; - uint64_t xscol:2; - uint64_t reserved_4_7:4; - uint64_t undflw:2; - uint64_t reserved_1_1:1; - uint64_t pko_nxa:1; - } s; - struct cvmx_agl_gmx_tx_int_reg_cn52xx { uint64_t reserved_18_63:46; uint64_t late_col:2; uint64_t reserved_14_15:2; @@ -1312,8 +1102,9 @@ union cvmx_agl_gmx_tx_int_reg { uint64_t undflw:2; uint64_t reserved_1_1:1; uint64_t pko_nxa:1; - } cn52xx; - struct cvmx_agl_gmx_tx_int_reg_cn52xx cn52xxp1; + } s; + struct cvmx_agl_gmx_tx_int_reg_s cn52xx; + struct cvmx_agl_gmx_tx_int_reg_s cn52xxp1; struct cvmx_agl_gmx_tx_int_reg_cn56xx { uint64_t reserved_17_63:47; uint64_t late_col:1; @@ -1327,8 +1118,6 @@ union cvmx_agl_gmx_tx_int_reg { uint64_t pko_nxa:1; } cn56xx; struct cvmx_agl_gmx_tx_int_reg_cn56xx cn56xxp1; - struct cvmx_agl_gmx_tx_int_reg_s cn63xx; - struct cvmx_agl_gmx_tx_int_reg_s cn63xxp1; }; union cvmx_agl_gmx_tx_jam { @@ -1341,8 +1130,6 @@ union cvmx_agl_gmx_tx_jam { struct cvmx_agl_gmx_tx_jam_s cn52xxp1; struct cvmx_agl_gmx_tx_jam_s cn56xx; struct cvmx_agl_gmx_tx_jam_s cn56xxp1; - struct cvmx_agl_gmx_tx_jam_s cn63xx; - struct cvmx_agl_gmx_tx_jam_s cn63xxp1; }; union cvmx_agl_gmx_tx_lfsr { @@ -1355,8 +1142,6 @@ union cvmx_agl_gmx_tx_lfsr { struct cvmx_agl_gmx_tx_lfsr_s cn52xxp1; struct cvmx_agl_gmx_tx_lfsr_s cn56xx; struct cvmx_agl_gmx_tx_lfsr_s cn56xxp1; - struct cvmx_agl_gmx_tx_lfsr_s cn63xx; - struct cvmx_agl_gmx_tx_lfsr_s cn63xxp1; }; union cvmx_agl_gmx_tx_ovr_bp { @@ -1380,8 +1165,6 @@ union cvmx_agl_gmx_tx_ovr_bp { uint64_t ign_full:1; } cn56xx; struct cvmx_agl_gmx_tx_ovr_bp_cn56xx cn56xxp1; - struct cvmx_agl_gmx_tx_ovr_bp_s cn63xx; - struct cvmx_agl_gmx_tx_ovr_bp_s cn63xxp1; }; union cvmx_agl_gmx_tx_pause_pkt_dmac { @@ -1394,8 +1177,6 @@ union cvmx_agl_gmx_tx_pause_pkt_dmac { struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn52xxp1; struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xx; struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xxp1; - struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn63xx; - struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn63xxp1; }; union cvmx_agl_gmx_tx_pause_pkt_type { @@ -1408,39 +1189,6 @@ union cvmx_agl_gmx_tx_pause_pkt_type { struct cvmx_agl_gmx_tx_pause_pkt_type_s cn52xxp1; struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xx; struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xxp1; - struct cvmx_agl_gmx_tx_pause_pkt_type_s cn63xx; - struct cvmx_agl_gmx_tx_pause_pkt_type_s cn63xxp1; -}; - -union cvmx_agl_prtx_ctl { - uint64_t u64; - struct cvmx_agl_prtx_ctl_s { - uint64_t drv_byp:1; - uint64_t reserved_62_62:1; - uint64_t cmp_pctl:6; - uint64_t reserved_54_55:2; - uint64_t cmp_nctl:6; - uint64_t reserved_46_47:2; - uint64_t drv_pctl:6; - uint64_t reserved_38_39:2; - uint64_t drv_nctl:6; - uint64_t reserved_29_31:3; - uint64_t clk_set:5; - uint64_t clkrx_byp:1; - uint64_t reserved_21_22:2; - uint64_t clkrx_set:5; - uint64_t clktx_byp:1; - uint64_t reserved_13_14:2; - uint64_t clktx_set:5; - uint64_t reserved_5_7:3; - uint64_t dllrst:1; - uint64_t comp:1; - uint64_t enable:1; - uint64_t clkrst:1; - uint64_t mode:1; - } s; - struct cvmx_agl_prtx_ctl_s cn63xx; - struct cvmx_agl_prtx_ctl_s cn63xxp1; }; #endif diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-asm.h b/trunk/arch/mips/include/asm/octeon/cvmx-asm.h index 5de5de95311b..b21d3fc1ef91 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-asm.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-asm.h @@ -114,17 +114,6 @@ #define CVMX_DCACHE_INVALIDATE \ { CVMX_SYNC; asm volatile ("cache 9, 0($0)" : : ); } -#define CVMX_CACHE(op, address, offset) \ - asm volatile ("cache " CVMX_TMP_STR(op) ", " CVMX_TMP_STR(offset) "(%[rbase])" \ - : : [rbase] "d" (address) ) -/* fetch and lock the state. */ -#define CVMX_CACHE_LCKL2(address, offset) CVMX_CACHE(31, address, offset) -/* unlock the state. */ -#define CVMX_CACHE_WBIL2(address, offset) CVMX_CACHE(23, address, offset) -/* invalidate the cache block and clear the USED bits for the block */ -#define CVMX_CACHE_WBIL2I(address, offset) CVMX_CACHE(3, address, offset) -/* load virtual tag and data for the L2 cache block into L2C_TAD0_TAG register */ -#define CVMX_CACHE_LTGL2I(address, offset) CVMX_CACHE(7, address, offset) #define CVMX_POP(result, input) \ asm ("pop %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input)) diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-ciu-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-ciu-defs.h index 27cead370411..f8f05b7764b7 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-ciu-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-ciu-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,61 +28,87 @@ #ifndef __CVMX_CIU_DEFS_H__ #define __CVMX_CIU_DEFS_H__ -#define CVMX_CIU_BIST (CVMX_ADD_IO_SEG(0x0001070000000730ull)) -#define CVMX_CIU_BLOCK_INT (CVMX_ADD_IO_SEG(0x00010700000007C0ull)) -#define CVMX_CIU_DINT (CVMX_ADD_IO_SEG(0x0001070000000720ull)) -#define CVMX_CIU_FUSE (CVMX_ADD_IO_SEG(0x0001070000000728ull)) -#define CVMX_CIU_GSTOP (CVMX_ADD_IO_SEG(0x0001070000000710ull)) -#define CVMX_CIU_INT33_SUM0 (CVMX_ADD_IO_SEG(0x0001070000000110ull)) -#define CVMX_CIU_INTX_EN0(offset) (CVMX_ADD_IO_SEG(0x0001070000000200ull) + ((offset) & 63) * 16) -#define CVMX_CIU_INTX_EN0_W1C(offset) (CVMX_ADD_IO_SEG(0x0001070000002200ull) + ((offset) & 63) * 16) -#define CVMX_CIU_INTX_EN0_W1S(offset) (CVMX_ADD_IO_SEG(0x0001070000006200ull) + ((offset) & 63) * 16) -#define CVMX_CIU_INTX_EN1(offset) (CVMX_ADD_IO_SEG(0x0001070000000208ull) + ((offset) & 63) * 16) -#define CVMX_CIU_INTX_EN1_W1C(offset) (CVMX_ADD_IO_SEG(0x0001070000002208ull) + ((offset) & 63) * 16) -#define CVMX_CIU_INTX_EN1_W1S(offset) (CVMX_ADD_IO_SEG(0x0001070000006208ull) + ((offset) & 63) * 16) -#define CVMX_CIU_INTX_EN4_0(offset) (CVMX_ADD_IO_SEG(0x0001070000000C80ull) + ((offset) & 15) * 16) -#define CVMX_CIU_INTX_EN4_0_W1C(offset) (CVMX_ADD_IO_SEG(0x0001070000002C80ull) + ((offset) & 15) * 16) -#define CVMX_CIU_INTX_EN4_0_W1S(offset) (CVMX_ADD_IO_SEG(0x0001070000006C80ull) + ((offset) & 15) * 16) -#define CVMX_CIU_INTX_EN4_1(offset) (CVMX_ADD_IO_SEG(0x0001070000000C88ull) + ((offset) & 15) * 16) -#define CVMX_CIU_INTX_EN4_1_W1C(offset) (CVMX_ADD_IO_SEG(0x0001070000002C88ull) + ((offset) & 15) * 16) -#define CVMX_CIU_INTX_EN4_1_W1S(offset) (CVMX_ADD_IO_SEG(0x0001070000006C88ull) + ((offset) & 15) * 16) -#define CVMX_CIU_INTX_SUM0(offset) (CVMX_ADD_IO_SEG(0x0001070000000000ull) + ((offset) & 63) * 8) -#define CVMX_CIU_INTX_SUM4(offset) (CVMX_ADD_IO_SEG(0x0001070000000C00ull) + ((offset) & 15) * 8) -#define CVMX_CIU_INT_DBG_SEL (CVMX_ADD_IO_SEG(0x00010700000007D0ull)) -#define CVMX_CIU_INT_SUM1 (CVMX_ADD_IO_SEG(0x0001070000000108ull)) -#define CVMX_CIU_MBOX_CLRX(offset) (CVMX_ADD_IO_SEG(0x0001070000000680ull) + ((offset) & 15) * 8) -#define CVMX_CIU_MBOX_SETX(offset) (CVMX_ADD_IO_SEG(0x0001070000000600ull) + ((offset) & 15) * 8) -#define CVMX_CIU_NMI (CVMX_ADD_IO_SEG(0x0001070000000718ull)) -#define CVMX_CIU_PCI_INTA (CVMX_ADD_IO_SEG(0x0001070000000750ull)) -#define CVMX_CIU_PP_DBG (CVMX_ADD_IO_SEG(0x0001070000000708ull)) -#define CVMX_CIU_PP_POKEX(offset) (CVMX_ADD_IO_SEG(0x0001070000000580ull) + ((offset) & 15) * 8) -#define CVMX_CIU_PP_RST (CVMX_ADD_IO_SEG(0x0001070000000700ull)) -#define CVMX_CIU_QLM0 (CVMX_ADD_IO_SEG(0x0001070000000780ull)) -#define CVMX_CIU_QLM1 (CVMX_ADD_IO_SEG(0x0001070000000788ull)) -#define CVMX_CIU_QLM2 (CVMX_ADD_IO_SEG(0x0001070000000790ull)) -#define CVMX_CIU_QLM_DCOK (CVMX_ADD_IO_SEG(0x0001070000000760ull)) -#define CVMX_CIU_QLM_JTGC (CVMX_ADD_IO_SEG(0x0001070000000768ull)) -#define CVMX_CIU_QLM_JTGD (CVMX_ADD_IO_SEG(0x0001070000000770ull)) -#define CVMX_CIU_SOFT_BIST (CVMX_ADD_IO_SEG(0x0001070000000738ull)) -#define CVMX_CIU_SOFT_PRST (CVMX_ADD_IO_SEG(0x0001070000000748ull)) -#define CVMX_CIU_SOFT_PRST1 (CVMX_ADD_IO_SEG(0x0001070000000758ull)) -#define CVMX_CIU_SOFT_RST (CVMX_ADD_IO_SEG(0x0001070000000740ull)) -#define CVMX_CIU_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001070000000480ull) + ((offset) & 3) * 8) -#define CVMX_CIU_WDOGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000500ull) + ((offset) & 15) * 8) +#define CVMX_CIU_BIST \ + CVMX_ADD_IO_SEG(0x0001070000000730ull) +#define CVMX_CIU_DINT \ + CVMX_ADD_IO_SEG(0x0001070000000720ull) +#define CVMX_CIU_FUSE \ + CVMX_ADD_IO_SEG(0x0001070000000728ull) +#define CVMX_CIU_GSTOP \ + CVMX_ADD_IO_SEG(0x0001070000000710ull) +#define CVMX_CIU_INTX_EN0(offset) \ + CVMX_ADD_IO_SEG(0x0001070000000200ull + (((offset) & 63) * 16)) +#define CVMX_CIU_INTX_EN0_W1C(offset) \ + CVMX_ADD_IO_SEG(0x0001070000002200ull + (((offset) & 63) * 16)) +#define CVMX_CIU_INTX_EN0_W1S(offset) \ + CVMX_ADD_IO_SEG(0x0001070000006200ull + (((offset) & 63) * 16)) +#define CVMX_CIU_INTX_EN1(offset) \ + CVMX_ADD_IO_SEG(0x0001070000000208ull + (((offset) & 63) * 16)) +#define CVMX_CIU_INTX_EN1_W1C(offset) \ + CVMX_ADD_IO_SEG(0x0001070000002208ull + (((offset) & 63) * 16)) +#define CVMX_CIU_INTX_EN1_W1S(offset) \ + CVMX_ADD_IO_SEG(0x0001070000006208ull + (((offset) & 63) * 16)) +#define CVMX_CIU_INTX_EN4_0(offset) \ + CVMX_ADD_IO_SEG(0x0001070000000C80ull + (((offset) & 15) * 16)) +#define CVMX_CIU_INTX_EN4_0_W1C(offset) \ + CVMX_ADD_IO_SEG(0x0001070000002C80ull + (((offset) & 15) * 16)) +#define CVMX_CIU_INTX_EN4_0_W1S(offset) \ + CVMX_ADD_IO_SEG(0x0001070000006C80ull + (((offset) & 15) * 16)) +#define CVMX_CIU_INTX_EN4_1(offset) \ + CVMX_ADD_IO_SEG(0x0001070000000C88ull + (((offset) & 15) * 16)) +#define CVMX_CIU_INTX_EN4_1_W1C(offset) \ + CVMX_ADD_IO_SEG(0x0001070000002C88ull + (((offset) & 15) * 16)) +#define CVMX_CIU_INTX_EN4_1_W1S(offset) \ + CVMX_ADD_IO_SEG(0x0001070000006C88ull + (((offset) & 15) * 16)) +#define CVMX_CIU_INTX_SUM0(offset) \ + CVMX_ADD_IO_SEG(0x0001070000000000ull + (((offset) & 63) * 8)) +#define CVMX_CIU_INTX_SUM4(offset) \ + CVMX_ADD_IO_SEG(0x0001070000000C00ull + (((offset) & 15) * 8)) +#define CVMX_CIU_INT_SUM1 \ + CVMX_ADD_IO_SEG(0x0001070000000108ull) +#define CVMX_CIU_MBOX_CLRX(offset) \ + CVMX_ADD_IO_SEG(0x0001070000000680ull + (((offset) & 15) * 8)) +#define CVMX_CIU_MBOX_SETX(offset) \ + CVMX_ADD_IO_SEG(0x0001070000000600ull + (((offset) & 15) * 8)) +#define CVMX_CIU_NMI \ + CVMX_ADD_IO_SEG(0x0001070000000718ull) +#define CVMX_CIU_PCI_INTA \ + CVMX_ADD_IO_SEG(0x0001070000000750ull) +#define CVMX_CIU_PP_DBG \ + CVMX_ADD_IO_SEG(0x0001070000000708ull) +#define CVMX_CIU_PP_POKEX(offset) \ + CVMX_ADD_IO_SEG(0x0001070000000580ull + (((offset) & 15) * 8)) +#define CVMX_CIU_PP_RST \ + CVMX_ADD_IO_SEG(0x0001070000000700ull) +#define CVMX_CIU_QLM_DCOK \ + CVMX_ADD_IO_SEG(0x0001070000000760ull) +#define CVMX_CIU_QLM_JTGC \ + CVMX_ADD_IO_SEG(0x0001070000000768ull) +#define CVMX_CIU_QLM_JTGD \ + CVMX_ADD_IO_SEG(0x0001070000000770ull) +#define CVMX_CIU_SOFT_BIST \ + CVMX_ADD_IO_SEG(0x0001070000000738ull) +#define CVMX_CIU_SOFT_PRST \ + CVMX_ADD_IO_SEG(0x0001070000000748ull) +#define CVMX_CIU_SOFT_PRST1 \ + CVMX_ADD_IO_SEG(0x0001070000000758ull) +#define CVMX_CIU_SOFT_RST \ + CVMX_ADD_IO_SEG(0x0001070000000740ull) +#define CVMX_CIU_TIMX(offset) \ + CVMX_ADD_IO_SEG(0x0001070000000480ull + (((offset) & 3) * 8)) +#define CVMX_CIU_WDOGX(offset) \ + CVMX_ADD_IO_SEG(0x0001070000000500ull + (((offset) & 15) * 8)) union cvmx_ciu_bist { uint64_t u64; struct cvmx_ciu_bist_s { - uint64_t reserved_5_63:59; - uint64_t bist:5; - } s; - struct cvmx_ciu_bist_cn30xx { uint64_t reserved_4_63:60; uint64_t bist:4; - } cn30xx; - struct cvmx_ciu_bist_cn30xx cn31xx; - struct cvmx_ciu_bist_cn30xx cn38xx; - struct cvmx_ciu_bist_cn30xx cn38xxp2; + } s; + struct cvmx_ciu_bist_s cn30xx; + struct cvmx_ciu_bist_s cn31xx; + struct cvmx_ciu_bist_s cn38xx; + struct cvmx_ciu_bist_s cn38xxp2; struct cvmx_ciu_bist_cn50xx { uint64_t reserved_2_63:62; uint64_t bist:2; @@ -92,57 +118,10 @@ union cvmx_ciu_bist { uint64_t bist:3; } cn52xx; struct cvmx_ciu_bist_cn52xx cn52xxp1; - struct cvmx_ciu_bist_cn30xx cn56xx; - struct cvmx_ciu_bist_cn30xx cn56xxp1; - struct cvmx_ciu_bist_cn30xx cn58xx; - struct cvmx_ciu_bist_cn30xx cn58xxp1; - struct cvmx_ciu_bist_s cn63xx; - struct cvmx_ciu_bist_s cn63xxp1; -}; - -union cvmx_ciu_block_int { - uint64_t u64; - struct cvmx_ciu_block_int_s { - uint64_t reserved_43_63:21; - uint64_t ptp:1; - uint64_t dpi:1; - uint64_t dfm:1; - uint64_t reserved_34_39:6; - uint64_t srio1:1; - uint64_t srio0:1; - uint64_t reserved_31_31:1; - uint64_t iob:1; - uint64_t reserved_29_29:1; - uint64_t agl:1; - uint64_t reserved_27_27:1; - uint64_t pem1:1; - uint64_t pem0:1; - uint64_t reserved_23_24:2; - uint64_t asxpcs0:1; - uint64_t reserved_21_21:1; - uint64_t pip:1; - uint64_t reserved_18_19:2; - uint64_t lmc0:1; - uint64_t l2c:1; - uint64_t reserved_15_15:1; - uint64_t rad:1; - uint64_t usb:1; - uint64_t pow:1; - uint64_t tim:1; - uint64_t pko:1; - uint64_t ipd:1; - uint64_t reserved_8_8:1; - uint64_t zip:1; - uint64_t dfa:1; - uint64_t fpa:1; - uint64_t key:1; - uint64_t sli:1; - uint64_t reserved_2_2:1; - uint64_t gmx0:1; - uint64_t mio:1; - } s; - struct cvmx_ciu_block_int_s cn63xx; - struct cvmx_ciu_block_int_s cn63xxp1; + struct cvmx_ciu_bist_s cn56xx; + struct cvmx_ciu_bist_s cn56xxp1; + struct cvmx_ciu_bist_s cn58xx; + struct cvmx_ciu_bist_s cn58xxp1; }; union cvmx_ciu_dint { @@ -174,11 +153,6 @@ union cvmx_ciu_dint { struct cvmx_ciu_dint_cn56xx cn56xxp1; struct cvmx_ciu_dint_s cn58xx; struct cvmx_ciu_dint_s cn58xxp1; - struct cvmx_ciu_dint_cn63xx { - uint64_t reserved_6_63:58; - uint64_t dint:6; - } cn63xx; - struct cvmx_ciu_dint_cn63xx cn63xxp1; }; union cvmx_ciu_fuse { @@ -210,11 +184,6 @@ union cvmx_ciu_fuse { struct cvmx_ciu_fuse_cn56xx cn56xxp1; struct cvmx_ciu_fuse_s cn58xx; struct cvmx_ciu_fuse_s cn58xxp1; - struct cvmx_ciu_fuse_cn63xx { - uint64_t reserved_6_63:58; - uint64_t fuse:6; - } cn63xx; - struct cvmx_ciu_fuse_cn63xx cn63xxp1; }; union cvmx_ciu_gstop { @@ -234,8 +203,6 @@ union cvmx_ciu_gstop { struct cvmx_ciu_gstop_s cn56xxp1; struct cvmx_ciu_gstop_s cn58xx; struct cvmx_ciu_gstop_s cn58xxp1; - struct cvmx_ciu_gstop_s cn63xx; - struct cvmx_ciu_gstop_s cn63xxp1; }; union cvmx_ciu_intx_en0 { @@ -376,8 +343,6 @@ union cvmx_ciu_intx_en0 { struct cvmx_ciu_intx_en0_cn56xx cn56xxp1; struct cvmx_ciu_intx_en0_cn38xx cn58xx; struct cvmx_ciu_intx_en0_cn38xx cn58xxp1; - struct cvmx_ciu_intx_en0_cn52xx cn63xx; - struct cvmx_ciu_intx_en0_cn52xx cn63xxp1; }; union cvmx_ciu_intx_en0_w1c { @@ -447,8 +412,6 @@ union cvmx_ciu_intx_en0_w1c { uint64_t gpio:16; uint64_t workq:16; } cn58xx; - struct cvmx_ciu_intx_en0_w1c_cn52xx cn63xx; - struct cvmx_ciu_intx_en0_w1c_cn52xx cn63xxp1; }; union cvmx_ciu_intx_en0_w1s { @@ -518,42 +481,12 @@ union cvmx_ciu_intx_en0_w1s { uint64_t gpio:16; uint64_t workq:16; } cn58xx; - struct cvmx_ciu_intx_en0_w1s_cn52xx cn63xx; - struct cvmx_ciu_intx_en0_w1s_cn52xx cn63xxp1; }; union cvmx_ciu_intx_en1 { uint64_t u64; struct cvmx_ciu_intx_en1_s { - uint64_t rst:1; - uint64_t reserved_57_62:6; - uint64_t dfm:1; - uint64_t reserved_53_55:3; - uint64_t lmc0:1; - uint64_t srio1:1; - uint64_t srio0:1; - uint64_t pem1:1; - uint64_t pem0:1; - uint64_t ptp:1; - uint64_t agl:1; - uint64_t reserved_37_45:9; - uint64_t agx0:1; - uint64_t dpi:1; - uint64_t sli:1; - uint64_t usb:1; - uint64_t dfa:1; - uint64_t key:1; - uint64_t rad:1; - uint64_t tim:1; - uint64_t zip:1; - uint64_t pko:1; - uint64_t pip:1; - uint64_t ipd:1; - uint64_t l2c:1; - uint64_t pow:1; - uint64_t fpa:1; - uint64_t iob:1; - uint64_t mio:1; + uint64_t reserved_20_63:44; uint64_t nand:1; uint64_t mii1:1; uint64_t usb1:1; @@ -598,76 +531,12 @@ union cvmx_ciu_intx_en1 { struct cvmx_ciu_intx_en1_cn56xx cn56xxp1; struct cvmx_ciu_intx_en1_cn38xx cn58xx; struct cvmx_ciu_intx_en1_cn38xx cn58xxp1; - struct cvmx_ciu_intx_en1_cn63xx { - uint64_t rst:1; - uint64_t reserved_57_62:6; - uint64_t dfm:1; - uint64_t reserved_53_55:3; - uint64_t lmc0:1; - uint64_t srio1:1; - uint64_t srio0:1; - uint64_t pem1:1; - uint64_t pem0:1; - uint64_t ptp:1; - uint64_t agl:1; - uint64_t reserved_37_45:9; - uint64_t agx0:1; - uint64_t dpi:1; - uint64_t sli:1; - uint64_t usb:1; - uint64_t dfa:1; - uint64_t key:1; - uint64_t rad:1; - uint64_t tim:1; - uint64_t zip:1; - uint64_t pko:1; - uint64_t pip:1; - uint64_t ipd:1; - uint64_t l2c:1; - uint64_t pow:1; - uint64_t fpa:1; - uint64_t iob:1; - uint64_t mio:1; - uint64_t nand:1; - uint64_t mii1:1; - uint64_t reserved_6_17:12; - uint64_t wdog:6; - } cn63xx; - struct cvmx_ciu_intx_en1_cn63xx cn63xxp1; }; union cvmx_ciu_intx_en1_w1c { uint64_t u64; struct cvmx_ciu_intx_en1_w1c_s { - uint64_t rst:1; - uint64_t reserved_57_62:6; - uint64_t dfm:1; - uint64_t reserved_53_55:3; - uint64_t lmc0:1; - uint64_t srio1:1; - uint64_t srio0:1; - uint64_t pem1:1; - uint64_t pem0:1; - uint64_t ptp:1; - uint64_t agl:1; - uint64_t reserved_37_45:9; - uint64_t agx0:1; - uint64_t dpi:1; - uint64_t sli:1; - uint64_t usb:1; - uint64_t dfa:1; - uint64_t key:1; - uint64_t rad:1; - uint64_t tim:1; - uint64_t zip:1; - uint64_t pko:1; - uint64_t pip:1; - uint64_t ipd:1; - uint64_t l2c:1; - uint64_t pow:1; - uint64_t fpa:1; - uint64_t iob:1; - uint64_t mio:1; + uint64_t reserved_20_63:44; uint64_t nand:1; uint64_t mii1:1; uint64_t usb1:1; @@ -691,76 +560,12 @@ union cvmx_ciu_intx_en1_w1c { uint64_t reserved_16_63:48; uint64_t wdog:16; } cn58xx; - struct cvmx_ciu_intx_en1_w1c_cn63xx { - uint64_t rst:1; - uint64_t reserved_57_62:6; - uint64_t dfm:1; - uint64_t reserved_53_55:3; - uint64_t lmc0:1; - uint64_t srio1:1; - uint64_t srio0:1; - uint64_t pem1:1; - uint64_t pem0:1; - uint64_t ptp:1; - uint64_t agl:1; - uint64_t reserved_37_45:9; - uint64_t agx0:1; - uint64_t dpi:1; - uint64_t sli:1; - uint64_t usb:1; - uint64_t dfa:1; - uint64_t key:1; - uint64_t rad:1; - uint64_t tim:1; - uint64_t zip:1; - uint64_t pko:1; - uint64_t pip:1; - uint64_t ipd:1; - uint64_t l2c:1; - uint64_t pow:1; - uint64_t fpa:1; - uint64_t iob:1; - uint64_t mio:1; - uint64_t nand:1; - uint64_t mii1:1; - uint64_t reserved_6_17:12; - uint64_t wdog:6; - } cn63xx; - struct cvmx_ciu_intx_en1_w1c_cn63xx cn63xxp1; }; union cvmx_ciu_intx_en1_w1s { uint64_t u64; struct cvmx_ciu_intx_en1_w1s_s { - uint64_t rst:1; - uint64_t reserved_57_62:6; - uint64_t dfm:1; - uint64_t reserved_53_55:3; - uint64_t lmc0:1; - uint64_t srio1:1; - uint64_t srio0:1; - uint64_t pem1:1; - uint64_t pem0:1; - uint64_t ptp:1; - uint64_t agl:1; - uint64_t reserved_37_45:9; - uint64_t agx0:1; - uint64_t dpi:1; - uint64_t sli:1; - uint64_t usb:1; - uint64_t dfa:1; - uint64_t key:1; - uint64_t rad:1; - uint64_t tim:1; - uint64_t zip:1; - uint64_t pko:1; - uint64_t pip:1; - uint64_t ipd:1; - uint64_t l2c:1; - uint64_t pow:1; - uint64_t fpa:1; - uint64_t iob:1; - uint64_t mio:1; + uint64_t reserved_20_63:44; uint64_t nand:1; uint64_t mii1:1; uint64_t usb1:1; @@ -784,42 +589,6 @@ union cvmx_ciu_intx_en1_w1s { uint64_t reserved_16_63:48; uint64_t wdog:16; } cn58xx; - struct cvmx_ciu_intx_en1_w1s_cn63xx { - uint64_t rst:1; - uint64_t reserved_57_62:6; - uint64_t dfm:1; - uint64_t reserved_53_55:3; - uint64_t lmc0:1; - uint64_t srio1:1; - uint64_t srio0:1; - uint64_t pem1:1; - uint64_t pem0:1; - uint64_t ptp:1; - uint64_t agl:1; - uint64_t reserved_37_45:9; - uint64_t agx0:1; - uint64_t dpi:1; - uint64_t sli:1; - uint64_t usb:1; - uint64_t dfa:1; - uint64_t key:1; - uint64_t rad:1; - uint64_t tim:1; - uint64_t zip:1; - uint64_t pko:1; - uint64_t pip:1; - uint64_t ipd:1; - uint64_t l2c:1; - uint64_t pow:1; - uint64_t fpa:1; - uint64_t iob:1; - uint64_t mio:1; - uint64_t nand:1; - uint64_t mii1:1; - uint64_t reserved_6_17:12; - uint64_t wdog:6; - } cn63xx; - struct cvmx_ciu_intx_en1_w1s_cn63xx cn63xxp1; }; union cvmx_ciu_intx_en4_0 { @@ -936,8 +705,6 @@ union cvmx_ciu_intx_en4_0 { uint64_t workq:16; } cn58xx; struct cvmx_ciu_intx_en4_0_cn58xx cn58xxp1; - struct cvmx_ciu_intx_en4_0_cn52xx cn63xx; - struct cvmx_ciu_intx_en4_0_cn52xx cn63xxp1; }; union cvmx_ciu_intx_en4_0_w1c { @@ -1007,8 +774,6 @@ union cvmx_ciu_intx_en4_0_w1c { uint64_t gpio:16; uint64_t workq:16; } cn58xx; - struct cvmx_ciu_intx_en4_0_w1c_cn52xx cn63xx; - struct cvmx_ciu_intx_en4_0_w1c_cn52xx cn63xxp1; }; union cvmx_ciu_intx_en4_0_w1s { @@ -1078,42 +843,12 @@ union cvmx_ciu_intx_en4_0_w1s { uint64_t gpio:16; uint64_t workq:16; } cn58xx; - struct cvmx_ciu_intx_en4_0_w1s_cn52xx cn63xx; - struct cvmx_ciu_intx_en4_0_w1s_cn52xx cn63xxp1; }; union cvmx_ciu_intx_en4_1 { uint64_t u64; struct cvmx_ciu_intx_en4_1_s { - uint64_t rst:1; - uint64_t reserved_57_62:6; - uint64_t dfm:1; - uint64_t reserved_53_55:3; - uint64_t lmc0:1; - uint64_t srio1:1; - uint64_t srio0:1; - uint64_t pem1:1; - uint64_t pem0:1; - uint64_t ptp:1; - uint64_t agl:1; - uint64_t reserved_37_45:9; - uint64_t agx0:1; - uint64_t dpi:1; - uint64_t sli:1; - uint64_t usb:1; - uint64_t dfa:1; - uint64_t key:1; - uint64_t rad:1; - uint64_t tim:1; - uint64_t zip:1; - uint64_t pko:1; - uint64_t pip:1; - uint64_t ipd:1; - uint64_t l2c:1; - uint64_t pow:1; - uint64_t fpa:1; - uint64_t iob:1; - uint64_t mio:1; + uint64_t reserved_20_63:44; uint64_t nand:1; uint64_t mii1:1; uint64_t usb1:1; @@ -1151,76 +886,12 @@ union cvmx_ciu_intx_en4_1 { uint64_t wdog:16; } cn58xx; struct cvmx_ciu_intx_en4_1_cn58xx cn58xxp1; - struct cvmx_ciu_intx_en4_1_cn63xx { - uint64_t rst:1; - uint64_t reserved_57_62:6; - uint64_t dfm:1; - uint64_t reserved_53_55:3; - uint64_t lmc0:1; - uint64_t srio1:1; - uint64_t srio0:1; - uint64_t pem1:1; - uint64_t pem0:1; - uint64_t ptp:1; - uint64_t agl:1; - uint64_t reserved_37_45:9; - uint64_t agx0:1; - uint64_t dpi:1; - uint64_t sli:1; - uint64_t usb:1; - uint64_t dfa:1; - uint64_t key:1; - uint64_t rad:1; - uint64_t tim:1; - uint64_t zip:1; - uint64_t pko:1; - uint64_t pip:1; - uint64_t ipd:1; - uint64_t l2c:1; - uint64_t pow:1; - uint64_t fpa:1; - uint64_t iob:1; - uint64_t mio:1; - uint64_t nand:1; - uint64_t mii1:1; - uint64_t reserved_6_17:12; - uint64_t wdog:6; - } cn63xx; - struct cvmx_ciu_intx_en4_1_cn63xx cn63xxp1; }; union cvmx_ciu_intx_en4_1_w1c { uint64_t u64; struct cvmx_ciu_intx_en4_1_w1c_s { - uint64_t rst:1; - uint64_t reserved_57_62:6; - uint64_t dfm:1; - uint64_t reserved_53_55:3; - uint64_t lmc0:1; - uint64_t srio1:1; - uint64_t srio0:1; - uint64_t pem1:1; - uint64_t pem0:1; - uint64_t ptp:1; - uint64_t agl:1; - uint64_t reserved_37_45:9; - uint64_t agx0:1; - uint64_t dpi:1; - uint64_t sli:1; - uint64_t usb:1; - uint64_t dfa:1; - uint64_t key:1; - uint64_t rad:1; - uint64_t tim:1; - uint64_t zip:1; - uint64_t pko:1; - uint64_t pip:1; - uint64_t ipd:1; - uint64_t l2c:1; - uint64_t pow:1; - uint64_t fpa:1; - uint64_t iob:1; - uint64_t mio:1; + uint64_t reserved_20_63:44; uint64_t nand:1; uint64_t mii1:1; uint64_t usb1:1; @@ -1244,76 +915,12 @@ union cvmx_ciu_intx_en4_1_w1c { uint64_t reserved_16_63:48; uint64_t wdog:16; } cn58xx; - struct cvmx_ciu_intx_en4_1_w1c_cn63xx { - uint64_t rst:1; - uint64_t reserved_57_62:6; - uint64_t dfm:1; - uint64_t reserved_53_55:3; - uint64_t lmc0:1; - uint64_t srio1:1; - uint64_t srio0:1; - uint64_t pem1:1; - uint64_t pem0:1; - uint64_t ptp:1; - uint64_t agl:1; - uint64_t reserved_37_45:9; - uint64_t agx0:1; - uint64_t dpi:1; - uint64_t sli:1; - uint64_t usb:1; - uint64_t dfa:1; - uint64_t key:1; - uint64_t rad:1; - uint64_t tim:1; - uint64_t zip:1; - uint64_t pko:1; - uint64_t pip:1; - uint64_t ipd:1; - uint64_t l2c:1; - uint64_t pow:1; - uint64_t fpa:1; - uint64_t iob:1; - uint64_t mio:1; - uint64_t nand:1; - uint64_t mii1:1; - uint64_t reserved_6_17:12; - uint64_t wdog:6; - } cn63xx; - struct cvmx_ciu_intx_en4_1_w1c_cn63xx cn63xxp1; }; union cvmx_ciu_intx_en4_1_w1s { uint64_t u64; struct cvmx_ciu_intx_en4_1_w1s_s { - uint64_t rst:1; - uint64_t reserved_57_62:6; - uint64_t dfm:1; - uint64_t reserved_53_55:3; - uint64_t lmc0:1; - uint64_t srio1:1; - uint64_t srio0:1; - uint64_t pem1:1; - uint64_t pem0:1; - uint64_t ptp:1; - uint64_t agl:1; - uint64_t reserved_37_45:9; - uint64_t agx0:1; - uint64_t dpi:1; - uint64_t sli:1; - uint64_t usb:1; - uint64_t dfa:1; - uint64_t key:1; - uint64_t rad:1; - uint64_t tim:1; - uint64_t zip:1; - uint64_t pko:1; - uint64_t pip:1; - uint64_t ipd:1; - uint64_t l2c:1; - uint64_t pow:1; - uint64_t fpa:1; - uint64_t iob:1; - uint64_t mio:1; + uint64_t reserved_20_63:44; uint64_t nand:1; uint64_t mii1:1; uint64_t usb1:1; @@ -1337,42 +944,6 @@ union cvmx_ciu_intx_en4_1_w1s { uint64_t reserved_16_63:48; uint64_t wdog:16; } cn58xx; - struct cvmx_ciu_intx_en4_1_w1s_cn63xx { - uint64_t rst:1; - uint64_t reserved_57_62:6; - uint64_t dfm:1; - uint64_t reserved_53_55:3; - uint64_t lmc0:1; - uint64_t srio1:1; - uint64_t srio0:1; - uint64_t pem1:1; - uint64_t pem0:1; - uint64_t ptp:1; - uint64_t agl:1; - uint64_t reserved_37_45:9; - uint64_t agx0:1; - uint64_t dpi:1; - uint64_t sli:1; - uint64_t usb:1; - uint64_t dfa:1; - uint64_t key:1; - uint64_t rad:1; - uint64_t tim:1; - uint64_t zip:1; - uint64_t pko:1; - uint64_t pip:1; - uint64_t ipd:1; - uint64_t l2c:1; - uint64_t pow:1; - uint64_t fpa:1; - uint64_t iob:1; - uint64_t mio:1; - uint64_t nand:1; - uint64_t mii1:1; - uint64_t reserved_6_17:12; - uint64_t wdog:6; - } cn63xx; - struct cvmx_ciu_intx_en4_1_w1s_cn63xx cn63xxp1; }; union cvmx_ciu_intx_sum0 { @@ -1513,8 +1084,6 @@ union cvmx_ciu_intx_sum0 { struct cvmx_ciu_intx_sum0_cn56xx cn56xxp1; struct cvmx_ciu_intx_sum0_cn38xx cn58xx; struct cvmx_ciu_intx_sum0_cn38xx cn58xxp1; - struct cvmx_ciu_intx_sum0_cn52xx cn63xx; - struct cvmx_ciu_intx_sum0_cn52xx cn63xxp1; }; union cvmx_ciu_intx_sum4 { @@ -1631,85 +1200,12 @@ union cvmx_ciu_intx_sum4 { uint64_t workq:16; } cn58xx; struct cvmx_ciu_intx_sum4_cn58xx cn58xxp1; - struct cvmx_ciu_intx_sum4_cn52xx cn63xx; - struct cvmx_ciu_intx_sum4_cn52xx cn63xxp1; -}; - -union cvmx_ciu_int33_sum0 { - uint64_t u64; - struct cvmx_ciu_int33_sum0_s { - uint64_t bootdma:1; - uint64_t mii:1; - uint64_t ipdppthr:1; - uint64_t powiq:1; - uint64_t twsi2:1; - uint64_t reserved_57_58:2; - uint64_t usb:1; - uint64_t timer:4; - uint64_t reserved_51_51:1; - uint64_t ipd_drp:1; - uint64_t reserved_49_49:1; - uint64_t gmx_drp:1; - uint64_t trace:1; - uint64_t rml:1; - uint64_t twsi:1; - uint64_t wdog_sum:1; - uint64_t pci_msi:4; - uint64_t pci_int:4; - uint64_t uart:2; - uint64_t mbox:2; - uint64_t gpio:16; - uint64_t workq:16; - } s; - struct cvmx_ciu_int33_sum0_s cn63xx; - struct cvmx_ciu_int33_sum0_s cn63xxp1; -}; - -union cvmx_ciu_int_dbg_sel { - uint64_t u64; - struct cvmx_ciu_int_dbg_sel_s { - uint64_t reserved_19_63:45; - uint64_t sel:3; - uint64_t reserved_10_15:6; - uint64_t irq:2; - uint64_t reserved_3_7:5; - uint64_t pp:3; - } s; - struct cvmx_ciu_int_dbg_sel_s cn63xx; }; union cvmx_ciu_int_sum1 { uint64_t u64; struct cvmx_ciu_int_sum1_s { - uint64_t rst:1; - uint64_t reserved_57_62:6; - uint64_t dfm:1; - uint64_t reserved_53_55:3; - uint64_t lmc0:1; - uint64_t srio1:1; - uint64_t srio0:1; - uint64_t pem1:1; - uint64_t pem0:1; - uint64_t ptp:1; - uint64_t agl:1; - uint64_t reserved_37_45:9; - uint64_t agx0:1; - uint64_t dpi:1; - uint64_t sli:1; - uint64_t usb:1; - uint64_t dfa:1; - uint64_t key:1; - uint64_t rad:1; - uint64_t tim:1; - uint64_t zip:1; - uint64_t pko:1; - uint64_t pip:1; - uint64_t ipd:1; - uint64_t l2c:1; - uint64_t pow:1; - uint64_t fpa:1; - uint64_t iob:1; - uint64_t mio:1; + uint64_t reserved_20_63:44; uint64_t nand:1; uint64_t mii1:1; uint64_t usb1:1; @@ -1754,42 +1250,6 @@ union cvmx_ciu_int_sum1 { struct cvmx_ciu_int_sum1_cn56xx cn56xxp1; struct cvmx_ciu_int_sum1_cn38xx cn58xx; struct cvmx_ciu_int_sum1_cn38xx cn58xxp1; - struct cvmx_ciu_int_sum1_cn63xx { - uint64_t rst:1; - uint64_t reserved_57_62:6; - uint64_t dfm:1; - uint64_t reserved_53_55:3; - uint64_t lmc0:1; - uint64_t srio1:1; - uint64_t srio0:1; - uint64_t pem1:1; - uint64_t pem0:1; - uint64_t ptp:1; - uint64_t agl:1; - uint64_t reserved_37_45:9; - uint64_t agx0:1; - uint64_t dpi:1; - uint64_t sli:1; - uint64_t usb:1; - uint64_t dfa:1; - uint64_t key:1; - uint64_t rad:1; - uint64_t tim:1; - uint64_t zip:1; - uint64_t pko:1; - uint64_t pip:1; - uint64_t ipd:1; - uint64_t l2c:1; - uint64_t pow:1; - uint64_t fpa:1; - uint64_t iob:1; - uint64_t mio:1; - uint64_t nand:1; - uint64_t mii1:1; - uint64_t reserved_6_17:12; - uint64_t wdog:6; - } cn63xx; - struct cvmx_ciu_int_sum1_cn63xx cn63xxp1; }; union cvmx_ciu_mbox_clrx { @@ -1809,8 +1269,6 @@ union cvmx_ciu_mbox_clrx { struct cvmx_ciu_mbox_clrx_s cn56xxp1; struct cvmx_ciu_mbox_clrx_s cn58xx; struct cvmx_ciu_mbox_clrx_s cn58xxp1; - struct cvmx_ciu_mbox_clrx_s cn63xx; - struct cvmx_ciu_mbox_clrx_s cn63xxp1; }; union cvmx_ciu_mbox_setx { @@ -1830,8 +1288,6 @@ union cvmx_ciu_mbox_setx { struct cvmx_ciu_mbox_setx_s cn56xxp1; struct cvmx_ciu_mbox_setx_s cn58xx; struct cvmx_ciu_mbox_setx_s cn58xxp1; - struct cvmx_ciu_mbox_setx_s cn63xx; - struct cvmx_ciu_mbox_setx_s cn63xxp1; }; union cvmx_ciu_nmi { @@ -1863,11 +1319,6 @@ union cvmx_ciu_nmi { struct cvmx_ciu_nmi_cn56xx cn56xxp1; struct cvmx_ciu_nmi_s cn58xx; struct cvmx_ciu_nmi_s cn58xxp1; - struct cvmx_ciu_nmi_cn63xx { - uint64_t reserved_6_63:58; - uint64_t nmi:6; - } cn63xx; - struct cvmx_ciu_nmi_cn63xx cn63xxp1; }; union cvmx_ciu_pci_inta { @@ -1887,8 +1338,6 @@ union cvmx_ciu_pci_inta { struct cvmx_ciu_pci_inta_s cn56xxp1; struct cvmx_ciu_pci_inta_s cn58xx; struct cvmx_ciu_pci_inta_s cn58xxp1; - struct cvmx_ciu_pci_inta_s cn63xx; - struct cvmx_ciu_pci_inta_s cn63xxp1; }; union cvmx_ciu_pp_dbg { @@ -1920,17 +1369,12 @@ union cvmx_ciu_pp_dbg { struct cvmx_ciu_pp_dbg_cn56xx cn56xxp1; struct cvmx_ciu_pp_dbg_s cn58xx; struct cvmx_ciu_pp_dbg_s cn58xxp1; - struct cvmx_ciu_pp_dbg_cn63xx { - uint64_t reserved_6_63:58; - uint64_t ppdbg:6; - } cn63xx; - struct cvmx_ciu_pp_dbg_cn63xx cn63xxp1; }; union cvmx_ciu_pp_pokex { uint64_t u64; struct cvmx_ciu_pp_pokex_s { - uint64_t poke:64; + uint64_t reserved_0_63:64; } s; struct cvmx_ciu_pp_pokex_s cn30xx; struct cvmx_ciu_pp_pokex_s cn31xx; @@ -1943,8 +1387,6 @@ union cvmx_ciu_pp_pokex { struct cvmx_ciu_pp_pokex_s cn56xxp1; struct cvmx_ciu_pp_pokex_s cn58xx; struct cvmx_ciu_pp_pokex_s cn58xxp1; - struct cvmx_ciu_pp_pokex_s cn63xx; - struct cvmx_ciu_pp_pokex_s cn63xxp1; }; union cvmx_ciu_pp_rst { @@ -1980,97 +1422,6 @@ union cvmx_ciu_pp_rst { struct cvmx_ciu_pp_rst_cn56xx cn56xxp1; struct cvmx_ciu_pp_rst_s cn58xx; struct cvmx_ciu_pp_rst_s cn58xxp1; - struct cvmx_ciu_pp_rst_cn63xx { - uint64_t reserved_6_63:58; - uint64_t rst:5; - uint64_t rst0:1; - } cn63xx; - struct cvmx_ciu_pp_rst_cn63xx cn63xxp1; -}; - -union cvmx_ciu_qlm0 { - uint64_t u64; - struct cvmx_ciu_qlm0_s { - uint64_t g2bypass:1; - uint64_t reserved_53_62:10; - uint64_t g2deemph:5; - uint64_t reserved_45_47:3; - uint64_t g2margin:5; - uint64_t reserved_32_39:8; - uint64_t txbypass:1; - uint64_t reserved_21_30:10; - uint64_t txdeemph:5; - uint64_t reserved_13_15:3; - uint64_t txmargin:5; - uint64_t reserved_4_7:4; - uint64_t lane_en:4; - } s; - struct cvmx_ciu_qlm0_s cn63xx; - struct cvmx_ciu_qlm0_cn63xxp1 { - uint64_t reserved_32_63:32; - uint64_t txbypass:1; - uint64_t reserved_20_30:11; - uint64_t txdeemph:4; - uint64_t reserved_13_15:3; - uint64_t txmargin:5; - uint64_t reserved_4_7:4; - uint64_t lane_en:4; - } cn63xxp1; -}; - -union cvmx_ciu_qlm1 { - uint64_t u64; - struct cvmx_ciu_qlm1_s { - uint64_t g2bypass:1; - uint64_t reserved_53_62:10; - uint64_t g2deemph:5; - uint64_t reserved_45_47:3; - uint64_t g2margin:5; - uint64_t reserved_32_39:8; - uint64_t txbypass:1; - uint64_t reserved_21_30:10; - uint64_t txdeemph:5; - uint64_t reserved_13_15:3; - uint64_t txmargin:5; - uint64_t reserved_4_7:4; - uint64_t lane_en:4; - } s; - struct cvmx_ciu_qlm1_s cn63xx; - struct cvmx_ciu_qlm1_cn63xxp1 { - uint64_t reserved_32_63:32; - uint64_t txbypass:1; - uint64_t reserved_20_30:11; - uint64_t txdeemph:4; - uint64_t reserved_13_15:3; - uint64_t txmargin:5; - uint64_t reserved_4_7:4; - uint64_t lane_en:4; - } cn63xxp1; -}; - -union cvmx_ciu_qlm2 { - uint64_t u64; - struct cvmx_ciu_qlm2_s { - uint64_t reserved_32_63:32; - uint64_t txbypass:1; - uint64_t reserved_21_30:10; - uint64_t txdeemph:5; - uint64_t reserved_13_15:3; - uint64_t txmargin:5; - uint64_t reserved_4_7:4; - uint64_t lane_en:4; - } s; - struct cvmx_ciu_qlm2_s cn63xx; - struct cvmx_ciu_qlm2_cn63xxp1 { - uint64_t reserved_32_63:32; - uint64_t txbypass:1; - uint64_t reserved_20_30:11; - uint64_t txdeemph:4; - uint64_t reserved_13_15:3; - uint64_t txmargin:5; - uint64_t reserved_4_7:4; - uint64_t lane_en:4; - } cn63xxp1; }; union cvmx_ciu_qlm_dcok { @@ -2108,15 +1459,6 @@ union cvmx_ciu_qlm_jtgc { struct cvmx_ciu_qlm_jtgc_cn52xx cn52xxp1; struct cvmx_ciu_qlm_jtgc_s cn56xx; struct cvmx_ciu_qlm_jtgc_s cn56xxp1; - struct cvmx_ciu_qlm_jtgc_cn63xx { - uint64_t reserved_11_63:53; - uint64_t clk_div:3; - uint64_t reserved_6_7:2; - uint64_t mux_sel:2; - uint64_t reserved_3_3:1; - uint64_t bypass:3; - } cn63xx; - struct cvmx_ciu_qlm_jtgc_cn63xx cn63xxp1; }; union cvmx_ciu_qlm_jtgd { @@ -2151,17 +1493,6 @@ union cvmx_ciu_qlm_jtgd { uint64_t shft_cnt:5; uint64_t shft_reg:32; } cn56xxp1; - struct cvmx_ciu_qlm_jtgd_cn63xx { - uint64_t capture:1; - uint64_t shift:1; - uint64_t update:1; - uint64_t reserved_43_60:18; - uint64_t select:3; - uint64_t reserved_37_39:3; - uint64_t shft_cnt:5; - uint64_t shft_reg:32; - } cn63xx; - struct cvmx_ciu_qlm_jtgd_cn63xx cn63xxp1; }; union cvmx_ciu_soft_bist { @@ -2181,8 +1512,6 @@ union cvmx_ciu_soft_bist { struct cvmx_ciu_soft_bist_s cn56xxp1; struct cvmx_ciu_soft_bist_s cn58xx; struct cvmx_ciu_soft_bist_s cn58xxp1; - struct cvmx_ciu_soft_bist_s cn63xx; - struct cvmx_ciu_soft_bist_s cn63xxp1; }; union cvmx_ciu_soft_prst { @@ -2207,8 +1536,6 @@ union cvmx_ciu_soft_prst { struct cvmx_ciu_soft_prst_cn52xx cn56xxp1; struct cvmx_ciu_soft_prst_s cn58xx; struct cvmx_ciu_soft_prst_s cn58xxp1; - struct cvmx_ciu_soft_prst_cn52xx cn63xx; - struct cvmx_ciu_soft_prst_cn52xx cn63xxp1; }; union cvmx_ciu_soft_prst1 { @@ -2221,8 +1548,6 @@ union cvmx_ciu_soft_prst1 { struct cvmx_ciu_soft_prst1_s cn52xxp1; struct cvmx_ciu_soft_prst1_s cn56xx; struct cvmx_ciu_soft_prst1_s cn56xxp1; - struct cvmx_ciu_soft_prst1_s cn63xx; - struct cvmx_ciu_soft_prst1_s cn63xxp1; }; union cvmx_ciu_soft_rst { @@ -2242,8 +1567,6 @@ union cvmx_ciu_soft_rst { struct cvmx_ciu_soft_rst_s cn56xxp1; struct cvmx_ciu_soft_rst_s cn58xx; struct cvmx_ciu_soft_rst_s cn58xxp1; - struct cvmx_ciu_soft_rst_s cn63xx; - struct cvmx_ciu_soft_rst_s cn63xxp1; }; union cvmx_ciu_timx { @@ -2264,8 +1587,6 @@ union cvmx_ciu_timx { struct cvmx_ciu_timx_s cn56xxp1; struct cvmx_ciu_timx_s cn58xx; struct cvmx_ciu_timx_s cn58xxp1; - struct cvmx_ciu_timx_s cn63xx; - struct cvmx_ciu_timx_s cn63xxp1; }; union cvmx_ciu_wdogx { @@ -2290,8 +1611,6 @@ union cvmx_ciu_wdogx { struct cvmx_ciu_wdogx_s cn56xxp1; struct cvmx_ciu_wdogx_s cn58xx; struct cvmx_ciu_wdogx_s cn58xxp1; - struct cvmx_ciu_wdogx_s cn63xx; - struct cvmx_ciu_wdogx_s cn63xxp1; }; #endif diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-gpio-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-gpio-defs.h index 395564e8d1f0..5fdd6ba48a05 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-gpio-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-gpio-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,22 +28,29 @@ #ifndef __CVMX_GPIO_DEFS_H__ #define __CVMX_GPIO_DEFS_H__ -#define CVMX_GPIO_BIT_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000800ull) + ((offset) & 15) * 8) -#define CVMX_GPIO_BOOT_ENA (CVMX_ADD_IO_SEG(0x00010700000008A8ull)) -#define CVMX_GPIO_CLK_GENX(offset) (CVMX_ADD_IO_SEG(0x00010700000008C0ull) + ((offset) & 3) * 8) -#define CVMX_GPIO_CLK_QLMX(offset) (CVMX_ADD_IO_SEG(0x00010700000008E0ull) + ((offset) & 1) * 8) -#define CVMX_GPIO_DBG_ENA (CVMX_ADD_IO_SEG(0x00010700000008A0ull)) -#define CVMX_GPIO_INT_CLR (CVMX_ADD_IO_SEG(0x0001070000000898ull)) -#define CVMX_GPIO_RX_DAT (CVMX_ADD_IO_SEG(0x0001070000000880ull)) -#define CVMX_GPIO_TX_CLR (CVMX_ADD_IO_SEG(0x0001070000000890ull)) -#define CVMX_GPIO_TX_SET (CVMX_ADD_IO_SEG(0x0001070000000888ull)) -#define CVMX_GPIO_XBIT_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000900ull) + ((offset) & 31) * 8 - 8*16) +#define CVMX_GPIO_BIT_CFGX(offset) \ + CVMX_ADD_IO_SEG(0x0001070000000800ull + (((offset) & 15) * 8)) +#define CVMX_GPIO_BOOT_ENA \ + CVMX_ADD_IO_SEG(0x00010700000008A8ull) +#define CVMX_GPIO_CLK_GENX(offset) \ + CVMX_ADD_IO_SEG(0x00010700000008C0ull + (((offset) & 3) * 8)) +#define CVMX_GPIO_DBG_ENA \ + CVMX_ADD_IO_SEG(0x00010700000008A0ull) +#define CVMX_GPIO_INT_CLR \ + CVMX_ADD_IO_SEG(0x0001070000000898ull) +#define CVMX_GPIO_RX_DAT \ + CVMX_ADD_IO_SEG(0x0001070000000880ull) +#define CVMX_GPIO_TX_CLR \ + CVMX_ADD_IO_SEG(0x0001070000000890ull) +#define CVMX_GPIO_TX_SET \ + CVMX_ADD_IO_SEG(0x0001070000000888ull) +#define CVMX_GPIO_XBIT_CFGX(offset) \ + CVMX_ADD_IO_SEG(0x0001070000000900ull + (((offset) & 31) * 8) - 8 * 16) union cvmx_gpio_bit_cfgx { uint64_t u64; struct cvmx_gpio_bit_cfgx_s { - uint64_t reserved_17_63:47; - uint64_t synce_sel:2; + uint64_t reserved_15_63:49; uint64_t clk_gen:1; uint64_t clk_sel:2; uint64_t fil_sel:4; @@ -66,24 +73,12 @@ union cvmx_gpio_bit_cfgx { struct cvmx_gpio_bit_cfgx_cn30xx cn38xx; struct cvmx_gpio_bit_cfgx_cn30xx cn38xxp2; struct cvmx_gpio_bit_cfgx_cn30xx cn50xx; - struct cvmx_gpio_bit_cfgx_cn52xx { - uint64_t reserved_15_63:49; - uint64_t clk_gen:1; - uint64_t clk_sel:2; - uint64_t fil_sel:4; - uint64_t fil_cnt:4; - uint64_t int_type:1; - uint64_t int_en:1; - uint64_t rx_xor:1; - uint64_t tx_oe:1; - } cn52xx; - struct cvmx_gpio_bit_cfgx_cn52xx cn52xxp1; - struct cvmx_gpio_bit_cfgx_cn52xx cn56xx; - struct cvmx_gpio_bit_cfgx_cn52xx cn56xxp1; + struct cvmx_gpio_bit_cfgx_s cn52xx; + struct cvmx_gpio_bit_cfgx_s cn52xxp1; + struct cvmx_gpio_bit_cfgx_s cn56xx; + struct cvmx_gpio_bit_cfgx_s cn56xxp1; struct cvmx_gpio_bit_cfgx_cn30xx cn58xx; struct cvmx_gpio_bit_cfgx_cn30xx cn58xxp1; - struct cvmx_gpio_bit_cfgx_s cn63xx; - struct cvmx_gpio_bit_cfgx_s cn63xxp1; }; union cvmx_gpio_boot_ena { @@ -108,19 +103,6 @@ union cvmx_gpio_clk_genx { struct cvmx_gpio_clk_genx_s cn52xxp1; struct cvmx_gpio_clk_genx_s cn56xx; struct cvmx_gpio_clk_genx_s cn56xxp1; - struct cvmx_gpio_clk_genx_s cn63xx; - struct cvmx_gpio_clk_genx_s cn63xxp1; -}; - -union cvmx_gpio_clk_qlmx { - uint64_t u64; - struct cvmx_gpio_clk_qlmx_s { - uint64_t reserved_3_63:61; - uint64_t div:1; - uint64_t lane_sel:2; - } s; - struct cvmx_gpio_clk_qlmx_s cn63xx; - struct cvmx_gpio_clk_qlmx_s cn63xxp1; }; union cvmx_gpio_dbg_ena { @@ -151,8 +133,6 @@ union cvmx_gpio_int_clr { struct cvmx_gpio_int_clr_s cn56xxp1; struct cvmx_gpio_int_clr_s cn58xx; struct cvmx_gpio_int_clr_s cn58xxp1; - struct cvmx_gpio_int_clr_s cn63xx; - struct cvmx_gpio_int_clr_s cn63xxp1; }; union cvmx_gpio_rx_dat { @@ -175,8 +155,6 @@ union cvmx_gpio_rx_dat { struct cvmx_gpio_rx_dat_cn38xx cn56xxp1; struct cvmx_gpio_rx_dat_cn38xx cn58xx; struct cvmx_gpio_rx_dat_cn38xx cn58xxp1; - struct cvmx_gpio_rx_dat_cn38xx cn63xx; - struct cvmx_gpio_rx_dat_cn38xx cn63xxp1; }; union cvmx_gpio_tx_clr { @@ -199,8 +177,6 @@ union cvmx_gpio_tx_clr { struct cvmx_gpio_tx_clr_cn38xx cn56xxp1; struct cvmx_gpio_tx_clr_cn38xx cn58xx; struct cvmx_gpio_tx_clr_cn38xx cn58xxp1; - struct cvmx_gpio_tx_clr_cn38xx cn63xx; - struct cvmx_gpio_tx_clr_cn38xx cn63xxp1; }; union cvmx_gpio_tx_set { @@ -223,8 +199,6 @@ union cvmx_gpio_tx_set { struct cvmx_gpio_tx_set_cn38xx cn56xxp1; struct cvmx_gpio_tx_set_cn38xx cn58xx; struct cvmx_gpio_tx_set_cn38xx cn58xxp1; - struct cvmx_gpio_tx_set_cn38xx cn63xx; - struct cvmx_gpio_tx_set_cn38xx cn63xxp1; }; union cvmx_gpio_xbit_cfgx { diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-iob-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-iob-defs.h index d7d856c2483d..0ee36baec500 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-iob-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-iob-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,59 +28,54 @@ #ifndef __CVMX_IOB_DEFS_H__ #define __CVMX_IOB_DEFS_H__ -#define CVMX_IOB_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011800F00007F8ull)) -#define CVMX_IOB_CTL_STATUS (CVMX_ADD_IO_SEG(0x00011800F0000050ull)) -#define CVMX_IOB_DWB_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000028ull)) -#define CVMX_IOB_FAU_TIMEOUT (CVMX_ADD_IO_SEG(0x00011800F0000000ull)) -#define CVMX_IOB_I2C_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000010ull)) -#define CVMX_IOB_INB_CONTROL_MATCH (CVMX_ADD_IO_SEG(0x00011800F0000078ull)) -#define CVMX_IOB_INB_CONTROL_MATCH_ENB (CVMX_ADD_IO_SEG(0x00011800F0000088ull)) -#define CVMX_IOB_INB_DATA_MATCH (CVMX_ADD_IO_SEG(0x00011800F0000070ull)) -#define CVMX_IOB_INB_DATA_MATCH_ENB (CVMX_ADD_IO_SEG(0x00011800F0000080ull)) -#define CVMX_IOB_INT_ENB (CVMX_ADD_IO_SEG(0x00011800F0000060ull)) -#define CVMX_IOB_INT_SUM (CVMX_ADD_IO_SEG(0x00011800F0000058ull)) -#define CVMX_IOB_N2C_L2C_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000020ull)) -#define CVMX_IOB_N2C_RSP_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000008ull)) -#define CVMX_IOB_OUTB_COM_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000040ull)) -#define CVMX_IOB_OUTB_CONTROL_MATCH (CVMX_ADD_IO_SEG(0x00011800F0000098ull)) -#define CVMX_IOB_OUTB_CONTROL_MATCH_ENB (CVMX_ADD_IO_SEG(0x00011800F00000A8ull)) -#define CVMX_IOB_OUTB_DATA_MATCH (CVMX_ADD_IO_SEG(0x00011800F0000090ull)) -#define CVMX_IOB_OUTB_DATA_MATCH_ENB (CVMX_ADD_IO_SEG(0x00011800F00000A0ull)) -#define CVMX_IOB_OUTB_FPA_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000048ull)) -#define CVMX_IOB_OUTB_REQ_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000038ull)) -#define CVMX_IOB_P2C_REQ_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000018ull)) -#define CVMX_IOB_PKT_ERR (CVMX_ADD_IO_SEG(0x00011800F0000068ull)) -#define CVMX_IOB_TO_CMB_CREDITS (CVMX_ADD_IO_SEG(0x00011800F00000B0ull)) +#define CVMX_IOB_BIST_STATUS \ + CVMX_ADD_IO_SEG(0x00011800F00007F8ull) +#define CVMX_IOB_CTL_STATUS \ + CVMX_ADD_IO_SEG(0x00011800F0000050ull) +#define CVMX_IOB_DWB_PRI_CNT \ + CVMX_ADD_IO_SEG(0x00011800F0000028ull) +#define CVMX_IOB_FAU_TIMEOUT \ + CVMX_ADD_IO_SEG(0x00011800F0000000ull) +#define CVMX_IOB_I2C_PRI_CNT \ + CVMX_ADD_IO_SEG(0x00011800F0000010ull) +#define CVMX_IOB_INB_CONTROL_MATCH \ + CVMX_ADD_IO_SEG(0x00011800F0000078ull) +#define CVMX_IOB_INB_CONTROL_MATCH_ENB \ + CVMX_ADD_IO_SEG(0x00011800F0000088ull) +#define CVMX_IOB_INB_DATA_MATCH \ + CVMX_ADD_IO_SEG(0x00011800F0000070ull) +#define CVMX_IOB_INB_DATA_MATCH_ENB \ + CVMX_ADD_IO_SEG(0x00011800F0000080ull) +#define CVMX_IOB_INT_ENB \ + CVMX_ADD_IO_SEG(0x00011800F0000060ull) +#define CVMX_IOB_INT_SUM \ + CVMX_ADD_IO_SEG(0x00011800F0000058ull) +#define CVMX_IOB_N2C_L2C_PRI_CNT \ + CVMX_ADD_IO_SEG(0x00011800F0000020ull) +#define CVMX_IOB_N2C_RSP_PRI_CNT \ + CVMX_ADD_IO_SEG(0x00011800F0000008ull) +#define CVMX_IOB_OUTB_COM_PRI_CNT \ + CVMX_ADD_IO_SEG(0x00011800F0000040ull) +#define CVMX_IOB_OUTB_CONTROL_MATCH \ + CVMX_ADD_IO_SEG(0x00011800F0000098ull) +#define CVMX_IOB_OUTB_CONTROL_MATCH_ENB \ + CVMX_ADD_IO_SEG(0x00011800F00000A8ull) +#define CVMX_IOB_OUTB_DATA_MATCH \ + CVMX_ADD_IO_SEG(0x00011800F0000090ull) +#define CVMX_IOB_OUTB_DATA_MATCH_ENB \ + CVMX_ADD_IO_SEG(0x00011800F00000A0ull) +#define CVMX_IOB_OUTB_FPA_PRI_CNT \ + CVMX_ADD_IO_SEG(0x00011800F0000048ull) +#define CVMX_IOB_OUTB_REQ_PRI_CNT \ + CVMX_ADD_IO_SEG(0x00011800F0000038ull) +#define CVMX_IOB_P2C_REQ_PRI_CNT \ + CVMX_ADD_IO_SEG(0x00011800F0000018ull) +#define CVMX_IOB_PKT_ERR \ + CVMX_ADD_IO_SEG(0x00011800F0000068ull) union cvmx_iob_bist_status { uint64_t u64; struct cvmx_iob_bist_status_s { - uint64_t reserved_23_63:41; - uint64_t xmdfif:1; - uint64_t xmcfif:1; - uint64_t iorfif:1; - uint64_t rsdfif:1; - uint64_t iocfif:1; - uint64_t icnrcb:1; - uint64_t icr0:1; - uint64_t icr1:1; - uint64_t icnr1:1; - uint64_t icnr0:1; - uint64_t ibdr0:1; - uint64_t ibdr1:1; - uint64_t ibr0:1; - uint64_t ibr1:1; - uint64_t icnrt:1; - uint64_t ibrq0:1; - uint64_t ibrq1:1; - uint64_t icrn0:1; - uint64_t icrn1:1; - uint64_t icrp0:1; - uint64_t icrp1:1; - uint64_t ibd:1; - uint64_t icd:1; - } s; - struct cvmx_iob_bist_status_cn30xx { uint64_t reserved_18_63:46; uint64_t icnrcb:1; uint64_t icr0:1; @@ -100,61 +95,41 @@ union cvmx_iob_bist_status { uint64_t icrp1:1; uint64_t ibd:1; uint64_t icd:1; - } cn30xx; - struct cvmx_iob_bist_status_cn30xx cn31xx; - struct cvmx_iob_bist_status_cn30xx cn38xx; - struct cvmx_iob_bist_status_cn30xx cn38xxp2; - struct cvmx_iob_bist_status_cn30xx cn50xx; - struct cvmx_iob_bist_status_cn30xx cn52xx; - struct cvmx_iob_bist_status_cn30xx cn52xxp1; - struct cvmx_iob_bist_status_cn30xx cn56xx; - struct cvmx_iob_bist_status_cn30xx cn56xxp1; - struct cvmx_iob_bist_status_cn30xx cn58xx; - struct cvmx_iob_bist_status_cn30xx cn58xxp1; - struct cvmx_iob_bist_status_s cn63xx; - struct cvmx_iob_bist_status_s cn63xxp1; + } s; + struct cvmx_iob_bist_status_s cn30xx; + struct cvmx_iob_bist_status_s cn31xx; + struct cvmx_iob_bist_status_s cn38xx; + struct cvmx_iob_bist_status_s cn38xxp2; + struct cvmx_iob_bist_status_s cn50xx; + struct cvmx_iob_bist_status_s cn52xx; + struct cvmx_iob_bist_status_s cn52xxp1; + struct cvmx_iob_bist_status_s cn56xx; + struct cvmx_iob_bist_status_s cn56xxp1; + struct cvmx_iob_bist_status_s cn58xx; + struct cvmx_iob_bist_status_s cn58xxp1; }; union cvmx_iob_ctl_status { uint64_t u64; struct cvmx_iob_ctl_status_s { - uint64_t reserved_10_63:54; - uint64_t xmc_per:4; - uint64_t rr_mode:1; - uint64_t outb_mat:1; - uint64_t inb_mat:1; - uint64_t pko_enb:1; - uint64_t dwb_enb:1; - uint64_t fau_end:1; - } s; - struct cvmx_iob_ctl_status_cn30xx { uint64_t reserved_5_63:59; uint64_t outb_mat:1; uint64_t inb_mat:1; uint64_t pko_enb:1; uint64_t dwb_enb:1; uint64_t fau_end:1; - } cn30xx; - struct cvmx_iob_ctl_status_cn30xx cn31xx; - struct cvmx_iob_ctl_status_cn30xx cn38xx; - struct cvmx_iob_ctl_status_cn30xx cn38xxp2; - struct cvmx_iob_ctl_status_cn30xx cn50xx; - struct cvmx_iob_ctl_status_cn52xx { - uint64_t reserved_6_63:58; - uint64_t rr_mode:1; - uint64_t outb_mat:1; - uint64_t inb_mat:1; - uint64_t pko_enb:1; - uint64_t dwb_enb:1; - uint64_t fau_end:1; - } cn52xx; - struct cvmx_iob_ctl_status_cn30xx cn52xxp1; - struct cvmx_iob_ctl_status_cn30xx cn56xx; - struct cvmx_iob_ctl_status_cn30xx cn56xxp1; - struct cvmx_iob_ctl_status_cn30xx cn58xx; - struct cvmx_iob_ctl_status_cn30xx cn58xxp1; - struct cvmx_iob_ctl_status_s cn63xx; - struct cvmx_iob_ctl_status_s cn63xxp1; + } s; + struct cvmx_iob_ctl_status_s cn30xx; + struct cvmx_iob_ctl_status_s cn31xx; + struct cvmx_iob_ctl_status_s cn38xx; + struct cvmx_iob_ctl_status_s cn38xxp2; + struct cvmx_iob_ctl_status_s cn50xx; + struct cvmx_iob_ctl_status_s cn52xx; + struct cvmx_iob_ctl_status_s cn52xxp1; + struct cvmx_iob_ctl_status_s cn56xx; + struct cvmx_iob_ctl_status_s cn56xxp1; + struct cvmx_iob_ctl_status_s cn58xx; + struct cvmx_iob_ctl_status_s cn58xxp1; }; union cvmx_iob_dwb_pri_cnt { @@ -172,8 +147,6 @@ union cvmx_iob_dwb_pri_cnt { struct cvmx_iob_dwb_pri_cnt_s cn56xxp1; struct cvmx_iob_dwb_pri_cnt_s cn58xx; struct cvmx_iob_dwb_pri_cnt_s cn58xxp1; - struct cvmx_iob_dwb_pri_cnt_s cn63xx; - struct cvmx_iob_dwb_pri_cnt_s cn63xxp1; }; union cvmx_iob_fau_timeout { @@ -194,8 +167,6 @@ union cvmx_iob_fau_timeout { struct cvmx_iob_fau_timeout_s cn56xxp1; struct cvmx_iob_fau_timeout_s cn58xx; struct cvmx_iob_fau_timeout_s cn58xxp1; - struct cvmx_iob_fau_timeout_s cn63xx; - struct cvmx_iob_fau_timeout_s cn63xxp1; }; union cvmx_iob_i2c_pri_cnt { @@ -213,8 +184,6 @@ union cvmx_iob_i2c_pri_cnt { struct cvmx_iob_i2c_pri_cnt_s cn56xxp1; struct cvmx_iob_i2c_pri_cnt_s cn58xx; struct cvmx_iob_i2c_pri_cnt_s cn58xxp1; - struct cvmx_iob_i2c_pri_cnt_s cn63xx; - struct cvmx_iob_i2c_pri_cnt_s cn63xxp1; }; union cvmx_iob_inb_control_match { @@ -237,8 +206,6 @@ union cvmx_iob_inb_control_match { struct cvmx_iob_inb_control_match_s cn56xxp1; struct cvmx_iob_inb_control_match_s cn58xx; struct cvmx_iob_inb_control_match_s cn58xxp1; - struct cvmx_iob_inb_control_match_s cn63xx; - struct cvmx_iob_inb_control_match_s cn63xxp1; }; union cvmx_iob_inb_control_match_enb { @@ -261,8 +228,6 @@ union cvmx_iob_inb_control_match_enb { struct cvmx_iob_inb_control_match_enb_s cn56xxp1; struct cvmx_iob_inb_control_match_enb_s cn58xx; struct cvmx_iob_inb_control_match_enb_s cn58xxp1; - struct cvmx_iob_inb_control_match_enb_s cn63xx; - struct cvmx_iob_inb_control_match_enb_s cn63xxp1; }; union cvmx_iob_inb_data_match { @@ -281,8 +246,6 @@ union cvmx_iob_inb_data_match { struct cvmx_iob_inb_data_match_s cn56xxp1; struct cvmx_iob_inb_data_match_s cn58xx; struct cvmx_iob_inb_data_match_s cn58xxp1; - struct cvmx_iob_inb_data_match_s cn63xx; - struct cvmx_iob_inb_data_match_s cn63xxp1; }; union cvmx_iob_inb_data_match_enb { @@ -301,8 +264,6 @@ union cvmx_iob_inb_data_match_enb { struct cvmx_iob_inb_data_match_enb_s cn56xxp1; struct cvmx_iob_inb_data_match_enb_s cn58xx; struct cvmx_iob_inb_data_match_enb_s cn58xxp1; - struct cvmx_iob_inb_data_match_enb_s cn63xx; - struct cvmx_iob_inb_data_match_enb_s cn63xxp1; }; union cvmx_iob_int_enb { @@ -333,8 +294,6 @@ union cvmx_iob_int_enb { struct cvmx_iob_int_enb_s cn56xxp1; struct cvmx_iob_int_enb_s cn58xx; struct cvmx_iob_int_enb_s cn58xxp1; - struct cvmx_iob_int_enb_s cn63xx; - struct cvmx_iob_int_enb_s cn63xxp1; }; union cvmx_iob_int_sum { @@ -365,8 +324,6 @@ union cvmx_iob_int_sum { struct cvmx_iob_int_sum_s cn56xxp1; struct cvmx_iob_int_sum_s cn58xx; struct cvmx_iob_int_sum_s cn58xxp1; - struct cvmx_iob_int_sum_s cn63xx; - struct cvmx_iob_int_sum_s cn63xxp1; }; union cvmx_iob_n2c_l2c_pri_cnt { @@ -384,8 +341,6 @@ union cvmx_iob_n2c_l2c_pri_cnt { struct cvmx_iob_n2c_l2c_pri_cnt_s cn56xxp1; struct cvmx_iob_n2c_l2c_pri_cnt_s cn58xx; struct cvmx_iob_n2c_l2c_pri_cnt_s cn58xxp1; - struct cvmx_iob_n2c_l2c_pri_cnt_s cn63xx; - struct cvmx_iob_n2c_l2c_pri_cnt_s cn63xxp1; }; union cvmx_iob_n2c_rsp_pri_cnt { @@ -403,8 +358,6 @@ union cvmx_iob_n2c_rsp_pri_cnt { struct cvmx_iob_n2c_rsp_pri_cnt_s cn56xxp1; struct cvmx_iob_n2c_rsp_pri_cnt_s cn58xx; struct cvmx_iob_n2c_rsp_pri_cnt_s cn58xxp1; - struct cvmx_iob_n2c_rsp_pri_cnt_s cn63xx; - struct cvmx_iob_n2c_rsp_pri_cnt_s cn63xxp1; }; union cvmx_iob_outb_com_pri_cnt { @@ -422,8 +375,6 @@ union cvmx_iob_outb_com_pri_cnt { struct cvmx_iob_outb_com_pri_cnt_s cn56xxp1; struct cvmx_iob_outb_com_pri_cnt_s cn58xx; struct cvmx_iob_outb_com_pri_cnt_s cn58xxp1; - struct cvmx_iob_outb_com_pri_cnt_s cn63xx; - struct cvmx_iob_outb_com_pri_cnt_s cn63xxp1; }; union cvmx_iob_outb_control_match { @@ -446,8 +397,6 @@ union cvmx_iob_outb_control_match { struct cvmx_iob_outb_control_match_s cn56xxp1; struct cvmx_iob_outb_control_match_s cn58xx; struct cvmx_iob_outb_control_match_s cn58xxp1; - struct cvmx_iob_outb_control_match_s cn63xx; - struct cvmx_iob_outb_control_match_s cn63xxp1; }; union cvmx_iob_outb_control_match_enb { @@ -470,8 +419,6 @@ union cvmx_iob_outb_control_match_enb { struct cvmx_iob_outb_control_match_enb_s cn56xxp1; struct cvmx_iob_outb_control_match_enb_s cn58xx; struct cvmx_iob_outb_control_match_enb_s cn58xxp1; - struct cvmx_iob_outb_control_match_enb_s cn63xx; - struct cvmx_iob_outb_control_match_enb_s cn63xxp1; }; union cvmx_iob_outb_data_match { @@ -490,8 +437,6 @@ union cvmx_iob_outb_data_match { struct cvmx_iob_outb_data_match_s cn56xxp1; struct cvmx_iob_outb_data_match_s cn58xx; struct cvmx_iob_outb_data_match_s cn58xxp1; - struct cvmx_iob_outb_data_match_s cn63xx; - struct cvmx_iob_outb_data_match_s cn63xxp1; }; union cvmx_iob_outb_data_match_enb { @@ -510,8 +455,6 @@ union cvmx_iob_outb_data_match_enb { struct cvmx_iob_outb_data_match_enb_s cn56xxp1; struct cvmx_iob_outb_data_match_enb_s cn58xx; struct cvmx_iob_outb_data_match_enb_s cn58xxp1; - struct cvmx_iob_outb_data_match_enb_s cn63xx; - struct cvmx_iob_outb_data_match_enb_s cn63xxp1; }; union cvmx_iob_outb_fpa_pri_cnt { @@ -529,8 +472,6 @@ union cvmx_iob_outb_fpa_pri_cnt { struct cvmx_iob_outb_fpa_pri_cnt_s cn56xxp1; struct cvmx_iob_outb_fpa_pri_cnt_s cn58xx; struct cvmx_iob_outb_fpa_pri_cnt_s cn58xxp1; - struct cvmx_iob_outb_fpa_pri_cnt_s cn63xx; - struct cvmx_iob_outb_fpa_pri_cnt_s cn63xxp1; }; union cvmx_iob_outb_req_pri_cnt { @@ -548,8 +489,6 @@ union cvmx_iob_outb_req_pri_cnt { struct cvmx_iob_outb_req_pri_cnt_s cn56xxp1; struct cvmx_iob_outb_req_pri_cnt_s cn58xx; struct cvmx_iob_outb_req_pri_cnt_s cn58xxp1; - struct cvmx_iob_outb_req_pri_cnt_s cn63xx; - struct cvmx_iob_outb_req_pri_cnt_s cn63xxp1; }; union cvmx_iob_p2c_req_pri_cnt { @@ -567,46 +506,25 @@ union cvmx_iob_p2c_req_pri_cnt { struct cvmx_iob_p2c_req_pri_cnt_s cn56xxp1; struct cvmx_iob_p2c_req_pri_cnt_s cn58xx; struct cvmx_iob_p2c_req_pri_cnt_s cn58xxp1; - struct cvmx_iob_p2c_req_pri_cnt_s cn63xx; - struct cvmx_iob_p2c_req_pri_cnt_s cn63xxp1; }; union cvmx_iob_pkt_err { uint64_t u64; struct cvmx_iob_pkt_err_s { - uint64_t reserved_12_63:52; - uint64_t vport:6; - uint64_t port:6; - } s; - struct cvmx_iob_pkt_err_cn30xx { uint64_t reserved_6_63:58; uint64_t port:6; - } cn30xx; - struct cvmx_iob_pkt_err_cn30xx cn31xx; - struct cvmx_iob_pkt_err_cn30xx cn38xx; - struct cvmx_iob_pkt_err_cn30xx cn38xxp2; - struct cvmx_iob_pkt_err_cn30xx cn50xx; - struct cvmx_iob_pkt_err_cn30xx cn52xx; - struct cvmx_iob_pkt_err_cn30xx cn52xxp1; - struct cvmx_iob_pkt_err_cn30xx cn56xx; - struct cvmx_iob_pkt_err_cn30xx cn56xxp1; - struct cvmx_iob_pkt_err_cn30xx cn58xx; - struct cvmx_iob_pkt_err_cn30xx cn58xxp1; - struct cvmx_iob_pkt_err_s cn63xx; - struct cvmx_iob_pkt_err_s cn63xxp1; -}; - -union cvmx_iob_to_cmb_credits { - uint64_t u64; - struct cvmx_iob_to_cmb_credits_s { - uint64_t reserved_9_63:55; - uint64_t pko_rd:3; - uint64_t ncb_rd:3; - uint64_t ncb_wr:3; } s; - struct cvmx_iob_to_cmb_credits_s cn52xx; - struct cvmx_iob_to_cmb_credits_s cn63xx; - struct cvmx_iob_to_cmb_credits_s cn63xxp1; + struct cvmx_iob_pkt_err_s cn30xx; + struct cvmx_iob_pkt_err_s cn31xx; + struct cvmx_iob_pkt_err_s cn38xx; + struct cvmx_iob_pkt_err_s cn38xxp2; + struct cvmx_iob_pkt_err_s cn50xx; + struct cvmx_iob_pkt_err_s cn52xx; + struct cvmx_iob_pkt_err_s cn52xxp1; + struct cvmx_iob_pkt_err_s cn56xx; + struct cvmx_iob_pkt_err_s cn56xxp1; + struct cvmx_iob_pkt_err_s cn58xx; + struct cvmx_iob_pkt_err_s cn58xxp1; }; #endif diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-ipd-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-ipd-defs.h index e0a5bfe88d04..f8b8fc657d2c 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-ipd-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-ipd-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,57 +28,104 @@ #ifndef __CVMX_IPD_DEFS_H__ #define __CVMX_IPD_DEFS_H__ -#define CVMX_IPD_1ST_MBUFF_SKIP (CVMX_ADD_IO_SEG(0x00014F0000000000ull)) -#define CVMX_IPD_1st_NEXT_PTR_BACK (CVMX_ADD_IO_SEG(0x00014F0000000150ull)) -#define CVMX_IPD_2nd_NEXT_PTR_BACK (CVMX_ADD_IO_SEG(0x00014F0000000158ull)) -#define CVMX_IPD_BIST_STATUS (CVMX_ADD_IO_SEG(0x00014F00000007F8ull)) -#define CVMX_IPD_BP_PRT_RED_END (CVMX_ADD_IO_SEG(0x00014F0000000328ull)) -#define CVMX_IPD_CLK_COUNT (CVMX_ADD_IO_SEG(0x00014F0000000338ull)) -#define CVMX_IPD_CTL_STATUS (CVMX_ADD_IO_SEG(0x00014F0000000018ull)) -#define CVMX_IPD_INT_ENB (CVMX_ADD_IO_SEG(0x00014F0000000160ull)) -#define CVMX_IPD_INT_SUM (CVMX_ADD_IO_SEG(0x00014F0000000168ull)) -#define CVMX_IPD_NOT_1ST_MBUFF_SKIP (CVMX_ADD_IO_SEG(0x00014F0000000008ull)) -#define CVMX_IPD_PACKET_MBUFF_SIZE (CVMX_ADD_IO_SEG(0x00014F0000000010ull)) -#define CVMX_IPD_PKT_PTR_VALID (CVMX_ADD_IO_SEG(0x00014F0000000358ull)) -#define CVMX_IPD_PORTX_BP_PAGE_CNT(offset) (CVMX_ADD_IO_SEG(0x00014F0000000028ull) + ((offset) & 63) * 8) -#define CVMX_IPD_PORTX_BP_PAGE_CNT2(offset) (CVMX_ADD_IO_SEG(0x00014F0000000368ull) + ((offset) & 63) * 8 - 8*36) -#define CVMX_IPD_PORTX_BP_PAGE_CNT3(offset) (CVMX_ADD_IO_SEG(0x00014F00000003D0ull) + ((offset) & 63) * 8 - 8*40) -#define CVMX_IPD_PORT_BP_COUNTERS2_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000388ull) + ((offset) & 63) * 8 - 8*36) -#define CVMX_IPD_PORT_BP_COUNTERS3_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F00000003B0ull) + ((offset) & 63) * 8 - 8*40) -#define CVMX_IPD_PORT_BP_COUNTERS_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F00000001B8ull) + ((offset) & 63) * 8) -#define CVMX_IPD_PORT_QOS_INTX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000808ull) + ((offset) & 7) * 8) -#define CVMX_IPD_PORT_QOS_INT_ENBX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000848ull) + ((offset) & 7) * 8) -#define CVMX_IPD_PORT_QOS_X_CNT(offset) (CVMX_ADD_IO_SEG(0x00014F0000000888ull) + ((offset) & 511) * 8) -#define CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000348ull)) -#define CVMX_IPD_PRC_PORT_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000350ull)) -#define CVMX_IPD_PTR_COUNT (CVMX_ADD_IO_SEG(0x00014F0000000320ull)) -#define CVMX_IPD_PWP_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000340ull)) -#define CVMX_IPD_QOS0_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(0) -#define CVMX_IPD_QOS1_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(1) -#define CVMX_IPD_QOS2_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(2) -#define CVMX_IPD_QOS3_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(3) -#define CVMX_IPD_QOS4_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(4) -#define CVMX_IPD_QOS5_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(5) -#define CVMX_IPD_QOS6_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(6) -#define CVMX_IPD_QOS7_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(7) -#define CVMX_IPD_QOSX_RED_MARKS(offset) (CVMX_ADD_IO_SEG(0x00014F0000000178ull) + ((offset) & 7) * 8) -#define CVMX_IPD_QUE0_FREE_PAGE_CNT (CVMX_ADD_IO_SEG(0x00014F0000000330ull)) -#define CVMX_IPD_RED_PORT_ENABLE (CVMX_ADD_IO_SEG(0x00014F00000002D8ull)) -#define CVMX_IPD_RED_PORT_ENABLE2 (CVMX_ADD_IO_SEG(0x00014F00000003A8ull)) -#define CVMX_IPD_RED_QUE0_PARAM CVMX_IPD_RED_QUEX_PARAM(0) -#define CVMX_IPD_RED_QUE1_PARAM CVMX_IPD_RED_QUEX_PARAM(1) -#define CVMX_IPD_RED_QUE2_PARAM CVMX_IPD_RED_QUEX_PARAM(2) -#define CVMX_IPD_RED_QUE3_PARAM CVMX_IPD_RED_QUEX_PARAM(3) -#define CVMX_IPD_RED_QUE4_PARAM CVMX_IPD_RED_QUEX_PARAM(4) -#define CVMX_IPD_RED_QUE5_PARAM CVMX_IPD_RED_QUEX_PARAM(5) -#define CVMX_IPD_RED_QUE6_PARAM CVMX_IPD_RED_QUEX_PARAM(6) -#define CVMX_IPD_RED_QUE7_PARAM CVMX_IPD_RED_QUEX_PARAM(7) -#define CVMX_IPD_RED_QUEX_PARAM(offset) (CVMX_ADD_IO_SEG(0x00014F00000002E0ull) + ((offset) & 7) * 8) -#define CVMX_IPD_SUB_PORT_BP_PAGE_CNT (CVMX_ADD_IO_SEG(0x00014F0000000148ull)) -#define CVMX_IPD_SUB_PORT_FCS (CVMX_ADD_IO_SEG(0x00014F0000000170ull)) -#define CVMX_IPD_SUB_PORT_QOS_CNT (CVMX_ADD_IO_SEG(0x00014F0000000800ull)) -#define CVMX_IPD_WQE_FPA_QUEUE (CVMX_ADD_IO_SEG(0x00014F0000000020ull)) -#define CVMX_IPD_WQE_PTR_VALID (CVMX_ADD_IO_SEG(0x00014F0000000360ull)) +#define CVMX_IPD_1ST_MBUFF_SKIP \ + CVMX_ADD_IO_SEG(0x00014F0000000000ull) +#define CVMX_IPD_1st_NEXT_PTR_BACK \ + CVMX_ADD_IO_SEG(0x00014F0000000150ull) +#define CVMX_IPD_2nd_NEXT_PTR_BACK \ + CVMX_ADD_IO_SEG(0x00014F0000000158ull) +#define CVMX_IPD_BIST_STATUS \ + CVMX_ADD_IO_SEG(0x00014F00000007F8ull) +#define CVMX_IPD_BP_PRT_RED_END \ + CVMX_ADD_IO_SEG(0x00014F0000000328ull) +#define CVMX_IPD_CLK_COUNT \ + CVMX_ADD_IO_SEG(0x00014F0000000338ull) +#define CVMX_IPD_CTL_STATUS \ + CVMX_ADD_IO_SEG(0x00014F0000000018ull) +#define CVMX_IPD_INT_ENB \ + CVMX_ADD_IO_SEG(0x00014F0000000160ull) +#define CVMX_IPD_INT_SUM \ + CVMX_ADD_IO_SEG(0x00014F0000000168ull) +#define CVMX_IPD_NOT_1ST_MBUFF_SKIP \ + CVMX_ADD_IO_SEG(0x00014F0000000008ull) +#define CVMX_IPD_PACKET_MBUFF_SIZE \ + CVMX_ADD_IO_SEG(0x00014F0000000010ull) +#define CVMX_IPD_PKT_PTR_VALID \ + CVMX_ADD_IO_SEG(0x00014F0000000358ull) +#define CVMX_IPD_PORTX_BP_PAGE_CNT(offset) \ + CVMX_ADD_IO_SEG(0x00014F0000000028ull + (((offset) & 63) * 8)) +#define CVMX_IPD_PORTX_BP_PAGE_CNT2(offset) \ + CVMX_ADD_IO_SEG(0x00014F0000000368ull + (((offset) & 63) * 8) - 8 * 36) +#define CVMX_IPD_PORT_BP_COUNTERS2_PAIRX(offset) \ + CVMX_ADD_IO_SEG(0x00014F0000000388ull + (((offset) & 63) * 8) - 8 * 36) +#define CVMX_IPD_PORT_BP_COUNTERS_PAIRX(offset) \ + CVMX_ADD_IO_SEG(0x00014F00000001B8ull + (((offset) & 63) * 8)) +#define CVMX_IPD_PORT_QOS_INTX(offset) \ + CVMX_ADD_IO_SEG(0x00014F0000000808ull + (((offset) & 7) * 8)) +#define CVMX_IPD_PORT_QOS_INT_ENBX(offset) \ + CVMX_ADD_IO_SEG(0x00014F0000000848ull + (((offset) & 7) * 8)) +#define CVMX_IPD_PORT_QOS_X_CNT(offset) \ + CVMX_ADD_IO_SEG(0x00014F0000000888ull + (((offset) & 511) * 8)) +#define CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL \ + CVMX_ADD_IO_SEG(0x00014F0000000348ull) +#define CVMX_IPD_PRC_PORT_PTR_FIFO_CTL \ + CVMX_ADD_IO_SEG(0x00014F0000000350ull) +#define CVMX_IPD_PTR_COUNT \ + CVMX_ADD_IO_SEG(0x00014F0000000320ull) +#define CVMX_IPD_PWP_PTR_FIFO_CTL \ + CVMX_ADD_IO_SEG(0x00014F0000000340ull) +#define CVMX_IPD_QOS0_RED_MARKS \ + CVMX_ADD_IO_SEG(0x00014F0000000178ull) +#define CVMX_IPD_QOS1_RED_MARKS \ + CVMX_ADD_IO_SEG(0x00014F0000000180ull) +#define CVMX_IPD_QOS2_RED_MARKS \ + CVMX_ADD_IO_SEG(0x00014F0000000188ull) +#define CVMX_IPD_QOS3_RED_MARKS \ + CVMX_ADD_IO_SEG(0x00014F0000000190ull) +#define CVMX_IPD_QOS4_RED_MARKS \ + CVMX_ADD_IO_SEG(0x00014F0000000198ull) +#define CVMX_IPD_QOS5_RED_MARKS \ + CVMX_ADD_IO_SEG(0x00014F00000001A0ull) +#define CVMX_IPD_QOS6_RED_MARKS \ + CVMX_ADD_IO_SEG(0x00014F00000001A8ull) +#define CVMX_IPD_QOS7_RED_MARKS \ + CVMX_ADD_IO_SEG(0x00014F00000001B0ull) +#define CVMX_IPD_QOSX_RED_MARKS(offset) \ + CVMX_ADD_IO_SEG(0x00014F0000000178ull + (((offset) & 7) * 8)) +#define CVMX_IPD_QUE0_FREE_PAGE_CNT \ + CVMX_ADD_IO_SEG(0x00014F0000000330ull) +#define CVMX_IPD_RED_PORT_ENABLE \ + CVMX_ADD_IO_SEG(0x00014F00000002D8ull) +#define CVMX_IPD_RED_PORT_ENABLE2 \ + CVMX_ADD_IO_SEG(0x00014F00000003A8ull) +#define CVMX_IPD_RED_QUE0_PARAM \ + CVMX_ADD_IO_SEG(0x00014F00000002E0ull) +#define CVMX_IPD_RED_QUE1_PARAM \ + CVMX_ADD_IO_SEG(0x00014F00000002E8ull) +#define CVMX_IPD_RED_QUE2_PARAM \ + CVMX_ADD_IO_SEG(0x00014F00000002F0ull) +#define CVMX_IPD_RED_QUE3_PARAM \ + CVMX_ADD_IO_SEG(0x00014F00000002F8ull) +#define CVMX_IPD_RED_QUE4_PARAM \ + CVMX_ADD_IO_SEG(0x00014F0000000300ull) +#define CVMX_IPD_RED_QUE5_PARAM \ + CVMX_ADD_IO_SEG(0x00014F0000000308ull) +#define CVMX_IPD_RED_QUE6_PARAM \ + CVMX_ADD_IO_SEG(0x00014F0000000310ull) +#define CVMX_IPD_RED_QUE7_PARAM \ + CVMX_ADD_IO_SEG(0x00014F0000000318ull) +#define CVMX_IPD_RED_QUEX_PARAM(offset) \ + CVMX_ADD_IO_SEG(0x00014F00000002E0ull + (((offset) & 7) * 8)) +#define CVMX_IPD_SUB_PORT_BP_PAGE_CNT \ + CVMX_ADD_IO_SEG(0x00014F0000000148ull) +#define CVMX_IPD_SUB_PORT_FCS \ + CVMX_ADD_IO_SEG(0x00014F0000000170ull) +#define CVMX_IPD_SUB_PORT_QOS_CNT \ + CVMX_ADD_IO_SEG(0x00014F0000000800ull) +#define CVMX_IPD_WQE_FPA_QUEUE \ + CVMX_ADD_IO_SEG(0x00014F0000000020ull) +#define CVMX_IPD_WQE_PTR_VALID \ + CVMX_ADD_IO_SEG(0x00014F0000000360ull) union cvmx_ipd_1st_mbuff_skip { uint64_t u64; @@ -97,8 +144,6 @@ union cvmx_ipd_1st_mbuff_skip { struct cvmx_ipd_1st_mbuff_skip_s cn56xxp1; struct cvmx_ipd_1st_mbuff_skip_s cn58xx; struct cvmx_ipd_1st_mbuff_skip_s cn58xxp1; - struct cvmx_ipd_1st_mbuff_skip_s cn63xx; - struct cvmx_ipd_1st_mbuff_skip_s cn63xxp1; }; union cvmx_ipd_1st_next_ptr_back { @@ -118,8 +163,6 @@ union cvmx_ipd_1st_next_ptr_back { struct cvmx_ipd_1st_next_ptr_back_s cn56xxp1; struct cvmx_ipd_1st_next_ptr_back_s cn58xx; struct cvmx_ipd_1st_next_ptr_back_s cn58xxp1; - struct cvmx_ipd_1st_next_ptr_back_s cn63xx; - struct cvmx_ipd_1st_next_ptr_back_s cn63xxp1; }; union cvmx_ipd_2nd_next_ptr_back { @@ -139,8 +182,6 @@ union cvmx_ipd_2nd_next_ptr_back { struct cvmx_ipd_2nd_next_ptr_back_s cn56xxp1; struct cvmx_ipd_2nd_next_ptr_back_s cn58xx; struct cvmx_ipd_2nd_next_ptr_back_s cn58xxp1; - struct cvmx_ipd_2nd_next_ptr_back_s cn63xx; - struct cvmx_ipd_2nd_next_ptr_back_s cn63xxp1; }; union cvmx_ipd_bist_status { @@ -195,15 +236,13 @@ union cvmx_ipd_bist_status { struct cvmx_ipd_bist_status_s cn56xxp1; struct cvmx_ipd_bist_status_cn30xx cn58xx; struct cvmx_ipd_bist_status_cn30xx cn58xxp1; - struct cvmx_ipd_bist_status_s cn63xx; - struct cvmx_ipd_bist_status_s cn63xxp1; }; union cvmx_ipd_bp_prt_red_end { uint64_t u64; struct cvmx_ipd_bp_prt_red_end_s { - uint64_t reserved_44_63:20; - uint64_t prt_enb:44; + uint64_t reserved_40_63:24; + uint64_t prt_enb:40; } s; struct cvmx_ipd_bp_prt_red_end_cn30xx { uint64_t reserved_36_63:28; @@ -213,17 +252,12 @@ union cvmx_ipd_bp_prt_red_end { struct cvmx_ipd_bp_prt_red_end_cn30xx cn38xx; struct cvmx_ipd_bp_prt_red_end_cn30xx cn38xxp2; struct cvmx_ipd_bp_prt_red_end_cn30xx cn50xx; - struct cvmx_ipd_bp_prt_red_end_cn52xx { - uint64_t reserved_40_63:24; - uint64_t prt_enb:40; - } cn52xx; - struct cvmx_ipd_bp_prt_red_end_cn52xx cn52xxp1; - struct cvmx_ipd_bp_prt_red_end_cn52xx cn56xx; - struct cvmx_ipd_bp_prt_red_end_cn52xx cn56xxp1; + struct cvmx_ipd_bp_prt_red_end_s cn52xx; + struct cvmx_ipd_bp_prt_red_end_s cn52xxp1; + struct cvmx_ipd_bp_prt_red_end_s cn56xx; + struct cvmx_ipd_bp_prt_red_end_s cn56xxp1; struct cvmx_ipd_bp_prt_red_end_cn30xx cn58xx; struct cvmx_ipd_bp_prt_red_end_cn30xx cn58xxp1; - struct cvmx_ipd_bp_prt_red_end_s cn63xx; - struct cvmx_ipd_bp_prt_red_end_s cn63xxp1; }; union cvmx_ipd_clk_count { @@ -242,17 +276,12 @@ union cvmx_ipd_clk_count { struct cvmx_ipd_clk_count_s cn56xxp1; struct cvmx_ipd_clk_count_s cn58xx; struct cvmx_ipd_clk_count_s cn58xxp1; - struct cvmx_ipd_clk_count_s cn63xx; - struct cvmx_ipd_clk_count_s cn63xxp1; }; union cvmx_ipd_ctl_status { uint64_t u64; struct cvmx_ipd_ctl_status_s { - uint64_t reserved_18_63:46; - uint64_t use_sop:1; - uint64_t rst_done:1; - uint64_t clken:1; + uint64_t reserved_15_63:49; uint64_t no_wptr:1; uint64_t pq_apkt:1; uint64_t pq_nabuf:1; @@ -293,27 +322,11 @@ union cvmx_ipd_ctl_status { uint64_t opc_mode:2; uint64_t ipd_en:1; } cn38xxp2; - struct cvmx_ipd_ctl_status_cn50xx { - uint64_t reserved_15_63:49; - uint64_t no_wptr:1; - uint64_t pq_apkt:1; - uint64_t pq_nabuf:1; - uint64_t ipd_full:1; - uint64_t pkt_off:1; - uint64_t len_m8:1; - uint64_t reset:1; - uint64_t addpkt:1; - uint64_t naddbuf:1; - uint64_t pkt_lend:1; - uint64_t wqe_lend:1; - uint64_t pbp_en:1; - uint64_t opc_mode:2; - uint64_t ipd_en:1; - } cn50xx; - struct cvmx_ipd_ctl_status_cn50xx cn52xx; - struct cvmx_ipd_ctl_status_cn50xx cn52xxp1; - struct cvmx_ipd_ctl_status_cn50xx cn56xx; - struct cvmx_ipd_ctl_status_cn50xx cn56xxp1; + struct cvmx_ipd_ctl_status_s cn50xx; + struct cvmx_ipd_ctl_status_s cn52xx; + struct cvmx_ipd_ctl_status_s cn52xxp1; + struct cvmx_ipd_ctl_status_s cn56xx; + struct cvmx_ipd_ctl_status_s cn56xxp1; struct cvmx_ipd_ctl_status_cn58xx { uint64_t reserved_12_63:52; uint64_t ipd_full:1; @@ -329,25 +342,6 @@ union cvmx_ipd_ctl_status { uint64_t ipd_en:1; } cn58xx; struct cvmx_ipd_ctl_status_cn58xx cn58xxp1; - struct cvmx_ipd_ctl_status_s cn63xx; - struct cvmx_ipd_ctl_status_cn63xxp1 { - uint64_t reserved_16_63:48; - uint64_t clken:1; - uint64_t no_wptr:1; - uint64_t pq_apkt:1; - uint64_t pq_nabuf:1; - uint64_t ipd_full:1; - uint64_t pkt_off:1; - uint64_t len_m8:1; - uint64_t reset:1; - uint64_t addpkt:1; - uint64_t naddbuf:1; - uint64_t pkt_lend:1; - uint64_t wqe_lend:1; - uint64_t pbp_en:1; - uint64_t opc_mode:2; - uint64_t ipd_en:1; - } cn63xxp1; }; union cvmx_ipd_int_enb { @@ -397,8 +391,6 @@ union cvmx_ipd_int_enb { struct cvmx_ipd_int_enb_s cn56xxp1; struct cvmx_ipd_int_enb_cn38xx cn58xx; struct cvmx_ipd_int_enb_cn38xx cn58xxp1; - struct cvmx_ipd_int_enb_s cn63xx; - struct cvmx_ipd_int_enb_s cn63xxp1; }; union cvmx_ipd_int_sum { @@ -448,8 +440,6 @@ union cvmx_ipd_int_sum { struct cvmx_ipd_int_sum_s cn56xxp1; struct cvmx_ipd_int_sum_cn38xx cn58xx; struct cvmx_ipd_int_sum_cn38xx cn58xxp1; - struct cvmx_ipd_int_sum_s cn63xx; - struct cvmx_ipd_int_sum_s cn63xxp1; }; union cvmx_ipd_not_1st_mbuff_skip { @@ -469,8 +459,6 @@ union cvmx_ipd_not_1st_mbuff_skip { struct cvmx_ipd_not_1st_mbuff_skip_s cn56xxp1; struct cvmx_ipd_not_1st_mbuff_skip_s cn58xx; struct cvmx_ipd_not_1st_mbuff_skip_s cn58xxp1; - struct cvmx_ipd_not_1st_mbuff_skip_s cn63xx; - struct cvmx_ipd_not_1st_mbuff_skip_s cn63xxp1; }; union cvmx_ipd_packet_mbuff_size { @@ -490,8 +478,6 @@ union cvmx_ipd_packet_mbuff_size { struct cvmx_ipd_packet_mbuff_size_s cn56xxp1; struct cvmx_ipd_packet_mbuff_size_s cn58xx; struct cvmx_ipd_packet_mbuff_size_s cn58xxp1; - struct cvmx_ipd_packet_mbuff_size_s cn63xx; - struct cvmx_ipd_packet_mbuff_size_s cn63xxp1; }; union cvmx_ipd_pkt_ptr_valid { @@ -510,8 +496,6 @@ union cvmx_ipd_pkt_ptr_valid { struct cvmx_ipd_pkt_ptr_valid_s cn56xxp1; struct cvmx_ipd_pkt_ptr_valid_s cn58xx; struct cvmx_ipd_pkt_ptr_valid_s cn58xxp1; - struct cvmx_ipd_pkt_ptr_valid_s cn63xx; - struct cvmx_ipd_pkt_ptr_valid_s cn63xxp1; }; union cvmx_ipd_portx_bp_page_cnt { @@ -532,8 +516,6 @@ union cvmx_ipd_portx_bp_page_cnt { struct cvmx_ipd_portx_bp_page_cnt_s cn56xxp1; struct cvmx_ipd_portx_bp_page_cnt_s cn58xx; struct cvmx_ipd_portx_bp_page_cnt_s cn58xxp1; - struct cvmx_ipd_portx_bp_page_cnt_s cn63xx; - struct cvmx_ipd_portx_bp_page_cnt_s cn63xxp1; }; union cvmx_ipd_portx_bp_page_cnt2 { @@ -547,19 +529,6 @@ union cvmx_ipd_portx_bp_page_cnt2 { struct cvmx_ipd_portx_bp_page_cnt2_s cn52xxp1; struct cvmx_ipd_portx_bp_page_cnt2_s cn56xx; struct cvmx_ipd_portx_bp_page_cnt2_s cn56xxp1; - struct cvmx_ipd_portx_bp_page_cnt2_s cn63xx; - struct cvmx_ipd_portx_bp_page_cnt2_s cn63xxp1; -}; - -union cvmx_ipd_portx_bp_page_cnt3 { - uint64_t u64; - struct cvmx_ipd_portx_bp_page_cnt3_s { - uint64_t reserved_18_63:46; - uint64_t bp_enb:1; - uint64_t page_cnt:17; - } s; - struct cvmx_ipd_portx_bp_page_cnt3_s cn63xx; - struct cvmx_ipd_portx_bp_page_cnt3_s cn63xxp1; }; union cvmx_ipd_port_bp_counters2_pairx { @@ -572,18 +541,6 @@ union cvmx_ipd_port_bp_counters2_pairx { struct cvmx_ipd_port_bp_counters2_pairx_s cn52xxp1; struct cvmx_ipd_port_bp_counters2_pairx_s cn56xx; struct cvmx_ipd_port_bp_counters2_pairx_s cn56xxp1; - struct cvmx_ipd_port_bp_counters2_pairx_s cn63xx; - struct cvmx_ipd_port_bp_counters2_pairx_s cn63xxp1; -}; - -union cvmx_ipd_port_bp_counters3_pairx { - uint64_t u64; - struct cvmx_ipd_port_bp_counters3_pairx_s { - uint64_t reserved_25_63:39; - uint64_t cnt_val:25; - } s; - struct cvmx_ipd_port_bp_counters3_pairx_s cn63xx; - struct cvmx_ipd_port_bp_counters3_pairx_s cn63xxp1; }; union cvmx_ipd_port_bp_counters_pairx { @@ -603,8 +560,6 @@ union cvmx_ipd_port_bp_counters_pairx { struct cvmx_ipd_port_bp_counters_pairx_s cn56xxp1; struct cvmx_ipd_port_bp_counters_pairx_s cn58xx; struct cvmx_ipd_port_bp_counters_pairx_s cn58xxp1; - struct cvmx_ipd_port_bp_counters_pairx_s cn63xx; - struct cvmx_ipd_port_bp_counters_pairx_s cn63xxp1; }; union cvmx_ipd_port_qos_x_cnt { @@ -617,8 +572,6 @@ union cvmx_ipd_port_qos_x_cnt { struct cvmx_ipd_port_qos_x_cnt_s cn52xxp1; struct cvmx_ipd_port_qos_x_cnt_s cn56xx; struct cvmx_ipd_port_qos_x_cnt_s cn56xxp1; - struct cvmx_ipd_port_qos_x_cnt_s cn63xx; - struct cvmx_ipd_port_qos_x_cnt_s cn63xxp1; }; union cvmx_ipd_port_qos_intx { @@ -630,8 +583,6 @@ union cvmx_ipd_port_qos_intx { struct cvmx_ipd_port_qos_intx_s cn52xxp1; struct cvmx_ipd_port_qos_intx_s cn56xx; struct cvmx_ipd_port_qos_intx_s cn56xxp1; - struct cvmx_ipd_port_qos_intx_s cn63xx; - struct cvmx_ipd_port_qos_intx_s cn63xxp1; }; union cvmx_ipd_port_qos_int_enbx { @@ -643,8 +594,6 @@ union cvmx_ipd_port_qos_int_enbx { struct cvmx_ipd_port_qos_int_enbx_s cn52xxp1; struct cvmx_ipd_port_qos_int_enbx_s cn56xx; struct cvmx_ipd_port_qos_int_enbx_s cn56xxp1; - struct cvmx_ipd_port_qos_int_enbx_s cn63xx; - struct cvmx_ipd_port_qos_int_enbx_s cn63xxp1; }; union cvmx_ipd_prc_hold_ptr_fifo_ctl { @@ -667,8 +616,6 @@ union cvmx_ipd_prc_hold_ptr_fifo_ctl { struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn56xxp1; struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn58xx; struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn58xxp1; - struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn63xx; - struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn63xxp1; }; union cvmx_ipd_prc_port_ptr_fifo_ctl { @@ -690,8 +637,6 @@ union cvmx_ipd_prc_port_ptr_fifo_ctl { struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn56xxp1; struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn58xx; struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn58xxp1; - struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn63xx; - struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn63xxp1; }; union cvmx_ipd_ptr_count { @@ -715,8 +660,6 @@ union cvmx_ipd_ptr_count { struct cvmx_ipd_ptr_count_s cn56xxp1; struct cvmx_ipd_ptr_count_s cn58xx; struct cvmx_ipd_ptr_count_s cn58xxp1; - struct cvmx_ipd_ptr_count_s cn63xx; - struct cvmx_ipd_ptr_count_s cn63xxp1; }; union cvmx_ipd_pwp_ptr_fifo_ctl { @@ -740,8 +683,6 @@ union cvmx_ipd_pwp_ptr_fifo_ctl { struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn56xxp1; struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn58xx; struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn58xxp1; - struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn63xx; - struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn63xxp1; }; union cvmx_ipd_qosx_red_marks { @@ -761,8 +702,6 @@ union cvmx_ipd_qosx_red_marks { struct cvmx_ipd_qosx_red_marks_s cn56xxp1; struct cvmx_ipd_qosx_red_marks_s cn58xx; struct cvmx_ipd_qosx_red_marks_s cn58xxp1; - struct cvmx_ipd_qosx_red_marks_s cn63xx; - struct cvmx_ipd_qosx_red_marks_s cn63xxp1; }; union cvmx_ipd_que0_free_page_cnt { @@ -782,8 +721,6 @@ union cvmx_ipd_que0_free_page_cnt { struct cvmx_ipd_que0_free_page_cnt_s cn56xxp1; struct cvmx_ipd_que0_free_page_cnt_s cn58xx; struct cvmx_ipd_que0_free_page_cnt_s cn58xxp1; - struct cvmx_ipd_que0_free_page_cnt_s cn63xx; - struct cvmx_ipd_que0_free_page_cnt_s cn63xxp1; }; union cvmx_ipd_red_port_enable { @@ -804,25 +741,18 @@ union cvmx_ipd_red_port_enable { struct cvmx_ipd_red_port_enable_s cn56xxp1; struct cvmx_ipd_red_port_enable_s cn58xx; struct cvmx_ipd_red_port_enable_s cn58xxp1; - struct cvmx_ipd_red_port_enable_s cn63xx; - struct cvmx_ipd_red_port_enable_s cn63xxp1; }; union cvmx_ipd_red_port_enable2 { uint64_t u64; struct cvmx_ipd_red_port_enable2_s { - uint64_t reserved_8_63:56; - uint64_t prt_enb:8; - } s; - struct cvmx_ipd_red_port_enable2_cn52xx { uint64_t reserved_4_63:60; uint64_t prt_enb:4; - } cn52xx; - struct cvmx_ipd_red_port_enable2_cn52xx cn52xxp1; - struct cvmx_ipd_red_port_enable2_cn52xx cn56xx; - struct cvmx_ipd_red_port_enable2_cn52xx cn56xxp1; - struct cvmx_ipd_red_port_enable2_s cn63xx; - struct cvmx_ipd_red_port_enable2_s cn63xxp1; + } s; + struct cvmx_ipd_red_port_enable2_s cn52xx; + struct cvmx_ipd_red_port_enable2_s cn52xxp1; + struct cvmx_ipd_red_port_enable2_s cn56xx; + struct cvmx_ipd_red_port_enable2_s cn56xxp1; }; union cvmx_ipd_red_quex_param { @@ -845,8 +775,6 @@ union cvmx_ipd_red_quex_param { struct cvmx_ipd_red_quex_param_s cn56xxp1; struct cvmx_ipd_red_quex_param_s cn58xx; struct cvmx_ipd_red_quex_param_s cn58xxp1; - struct cvmx_ipd_red_quex_param_s cn63xx; - struct cvmx_ipd_red_quex_param_s cn63xxp1; }; union cvmx_ipd_sub_port_bp_page_cnt { @@ -867,8 +795,6 @@ union cvmx_ipd_sub_port_bp_page_cnt { struct cvmx_ipd_sub_port_bp_page_cnt_s cn56xxp1; struct cvmx_ipd_sub_port_bp_page_cnt_s cn58xx; struct cvmx_ipd_sub_port_bp_page_cnt_s cn58xxp1; - struct cvmx_ipd_sub_port_bp_page_cnt_s cn63xx; - struct cvmx_ipd_sub_port_bp_page_cnt_s cn63xxp1; }; union cvmx_ipd_sub_port_fcs { @@ -896,8 +822,6 @@ union cvmx_ipd_sub_port_fcs { struct cvmx_ipd_sub_port_fcs_s cn56xxp1; struct cvmx_ipd_sub_port_fcs_cn38xx cn58xx; struct cvmx_ipd_sub_port_fcs_cn38xx cn58xxp1; - struct cvmx_ipd_sub_port_fcs_s cn63xx; - struct cvmx_ipd_sub_port_fcs_s cn63xxp1; }; union cvmx_ipd_sub_port_qos_cnt { @@ -911,8 +835,6 @@ union cvmx_ipd_sub_port_qos_cnt { struct cvmx_ipd_sub_port_qos_cnt_s cn52xxp1; struct cvmx_ipd_sub_port_qos_cnt_s cn56xx; struct cvmx_ipd_sub_port_qos_cnt_s cn56xxp1; - struct cvmx_ipd_sub_port_qos_cnt_s cn63xx; - struct cvmx_ipd_sub_port_qos_cnt_s cn63xxp1; }; union cvmx_ipd_wqe_fpa_queue { @@ -932,8 +854,6 @@ union cvmx_ipd_wqe_fpa_queue { struct cvmx_ipd_wqe_fpa_queue_s cn56xxp1; struct cvmx_ipd_wqe_fpa_queue_s cn58xx; struct cvmx_ipd_wqe_fpa_queue_s cn58xxp1; - struct cvmx_ipd_wqe_fpa_queue_s cn63xx; - struct cvmx_ipd_wqe_fpa_queue_s cn63xxp1; }; union cvmx_ipd_wqe_ptr_valid { @@ -952,8 +872,6 @@ union cvmx_ipd_wqe_ptr_valid { struct cvmx_ipd_wqe_ptr_valid_s cn56xxp1; struct cvmx_ipd_wqe_ptr_valid_s cn58xx; struct cvmx_ipd_wqe_ptr_valid_s cn58xxp1; - struct cvmx_ipd_wqe_ptr_valid_s cn63xx; - struct cvmx_ipd_wqe_ptr_valid_s cn63xxp1; }; #endif diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-l2c-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-l2c-defs.h index 7a50a0beb472..337583842b51 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-l2c-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-l2c-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,113 +28,70 @@ #ifndef __CVMX_L2C_DEFS_H__ #define __CVMX_L2C_DEFS_H__ -#define CVMX_L2C_BIG_CTL (CVMX_ADD_IO_SEG(0x0001180080800030ull)) -#define CVMX_L2C_BST (CVMX_ADD_IO_SEG(0x00011800808007F8ull)) -#define CVMX_L2C_BST0 (CVMX_ADD_IO_SEG(0x00011800800007F8ull)) -#define CVMX_L2C_BST1 (CVMX_ADD_IO_SEG(0x00011800800007F0ull)) -#define CVMX_L2C_BST2 (CVMX_ADD_IO_SEG(0x00011800800007E8ull)) -#define CVMX_L2C_BST_MEMX(block_id) (CVMX_ADD_IO_SEG(0x0001180080C007F8ull)) -#define CVMX_L2C_BST_TDTX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007F0ull)) -#define CVMX_L2C_BST_TTGX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007F8ull)) -#define CVMX_L2C_CFG (CVMX_ADD_IO_SEG(0x0001180080000000ull)) -#define CVMX_L2C_COP0_MAPX(offset) (CVMX_ADD_IO_SEG(0x0001180080940000ull) + ((offset) & 16383) * 8) -#define CVMX_L2C_CTL (CVMX_ADD_IO_SEG(0x0001180080800000ull)) -#define CVMX_L2C_DBG (CVMX_ADD_IO_SEG(0x0001180080000030ull)) -#define CVMX_L2C_DUT (CVMX_ADD_IO_SEG(0x0001180080000050ull)) -#define CVMX_L2C_DUT_MAPX(offset) (CVMX_ADD_IO_SEG(0x0001180080E00000ull) + ((offset) & 2047) * 8) -#define CVMX_L2C_ERR_TDTX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007E0ull)) -#define CVMX_L2C_ERR_TTGX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007E8ull)) -#define CVMX_L2C_ERR_VBFX(block_id) (CVMX_ADD_IO_SEG(0x0001180080C007F0ull)) -#define CVMX_L2C_ERR_XMC (CVMX_ADD_IO_SEG(0x00011800808007D8ull)) -#define CVMX_L2C_GRPWRR0 (CVMX_ADD_IO_SEG(0x00011800800000C8ull)) -#define CVMX_L2C_GRPWRR1 (CVMX_ADD_IO_SEG(0x00011800800000D0ull)) -#define CVMX_L2C_INT_EN (CVMX_ADD_IO_SEG(0x0001180080000100ull)) -#define CVMX_L2C_INT_ENA (CVMX_ADD_IO_SEG(0x0001180080800020ull)) -#define CVMX_L2C_INT_REG (CVMX_ADD_IO_SEG(0x0001180080800018ull)) -#define CVMX_L2C_INT_STAT (CVMX_ADD_IO_SEG(0x00011800800000F8ull)) -#define CVMX_L2C_IOCX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800420ull)) -#define CVMX_L2C_IORX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800428ull)) -#define CVMX_L2C_LCKBASE (CVMX_ADD_IO_SEG(0x0001180080000058ull)) -#define CVMX_L2C_LCKOFF (CVMX_ADD_IO_SEG(0x0001180080000060ull)) -#define CVMX_L2C_LFB0 (CVMX_ADD_IO_SEG(0x0001180080000038ull)) -#define CVMX_L2C_LFB1 (CVMX_ADD_IO_SEG(0x0001180080000040ull)) -#define CVMX_L2C_LFB2 (CVMX_ADD_IO_SEG(0x0001180080000048ull)) -#define CVMX_L2C_LFB3 (CVMX_ADD_IO_SEG(0x00011800800000B8ull)) -#define CVMX_L2C_OOB (CVMX_ADD_IO_SEG(0x00011800800000D8ull)) -#define CVMX_L2C_OOB1 (CVMX_ADD_IO_SEG(0x00011800800000E0ull)) -#define CVMX_L2C_OOB2 (CVMX_ADD_IO_SEG(0x00011800800000E8ull)) -#define CVMX_L2C_OOB3 (CVMX_ADD_IO_SEG(0x00011800800000F0ull)) -#define CVMX_L2C_PFC0 CVMX_L2C_PFCX(0) -#define CVMX_L2C_PFC1 CVMX_L2C_PFCX(1) -#define CVMX_L2C_PFC2 CVMX_L2C_PFCX(2) -#define CVMX_L2C_PFC3 CVMX_L2C_PFCX(3) -#define CVMX_L2C_PFCTL (CVMX_ADD_IO_SEG(0x0001180080000090ull)) -#define CVMX_L2C_PFCX(offset) (CVMX_ADD_IO_SEG(0x0001180080000098ull) + ((offset) & 3) * 8) -#define CVMX_L2C_PPGRP (CVMX_ADD_IO_SEG(0x00011800800000C0ull)) -#define CVMX_L2C_QOS_IOBX(block_id) (CVMX_ADD_IO_SEG(0x0001180080880200ull)) -#define CVMX_L2C_QOS_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080880000ull) + ((offset) & 7) * 8) -#define CVMX_L2C_QOS_WGT (CVMX_ADD_IO_SEG(0x0001180080800008ull)) -#define CVMX_L2C_RSCX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800410ull)) -#define CVMX_L2C_RSDX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800418ull)) -#define CVMX_L2C_SPAR0 (CVMX_ADD_IO_SEG(0x0001180080000068ull)) -#define CVMX_L2C_SPAR1 (CVMX_ADD_IO_SEG(0x0001180080000070ull)) -#define CVMX_L2C_SPAR2 (CVMX_ADD_IO_SEG(0x0001180080000078ull)) -#define CVMX_L2C_SPAR3 (CVMX_ADD_IO_SEG(0x0001180080000080ull)) -#define CVMX_L2C_SPAR4 (CVMX_ADD_IO_SEG(0x0001180080000088ull)) -#define CVMX_L2C_TADX_ECC0(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00018ull)) -#define CVMX_L2C_TADX_ECC1(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00020ull)) -#define CVMX_L2C_TADX_IEN(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00000ull)) -#define CVMX_L2C_TADX_INT(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00028ull)) -#define CVMX_L2C_TADX_PFC0(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00400ull)) -#define CVMX_L2C_TADX_PFC1(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00408ull)) -#define CVMX_L2C_TADX_PFC2(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00410ull)) -#define CVMX_L2C_TADX_PFC3(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00418ull)) -#define CVMX_L2C_TADX_PRF(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00008ull)) -#define CVMX_L2C_TADX_TAG(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00010ull)) -#define CVMX_L2C_VER_ID (CVMX_ADD_IO_SEG(0x00011800808007E0ull)) -#define CVMX_L2C_VER_IOB (CVMX_ADD_IO_SEG(0x00011800808007F0ull)) -#define CVMX_L2C_VER_MSC (CVMX_ADD_IO_SEG(0x00011800808007D0ull)) -#define CVMX_L2C_VER_PP (CVMX_ADD_IO_SEG(0x00011800808007E8ull)) -#define CVMX_L2C_VIRTID_IOBX(block_id) (CVMX_ADD_IO_SEG(0x00011800808C0200ull)) -#define CVMX_L2C_VIRTID_PPX(offset) (CVMX_ADD_IO_SEG(0x00011800808C0000ull) + ((offset) & 7) * 8) -#define CVMX_L2C_VRT_CTL (CVMX_ADD_IO_SEG(0x0001180080800010ull)) -#define CVMX_L2C_VRT_MEMX(offset) (CVMX_ADD_IO_SEG(0x0001180080900000ull) + ((offset) & 1023) * 8) -#define CVMX_L2C_WPAR_IOBX(block_id) (CVMX_ADD_IO_SEG(0x0001180080840200ull)) -#define CVMX_L2C_WPAR_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080840000ull) + ((offset) & 7) * 8) -#define CVMX_L2C_XMCX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800400ull)) -#define CVMX_L2C_XMC_CMD (CVMX_ADD_IO_SEG(0x0001180080800028ull)) -#define CVMX_L2C_XMDX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800408ull)) - -union cvmx_l2c_big_ctl { - uint64_t u64; - struct cvmx_l2c_big_ctl_s { - uint64_t reserved_8_63:56; - uint64_t maxdram:4; - uint64_t reserved_1_3:3; - uint64_t disable:1; - } s; - struct cvmx_l2c_big_ctl_s cn63xx; -}; - -union cvmx_l2c_bst { - uint64_t u64; - struct cvmx_l2c_bst_s { - uint64_t reserved_38_63:26; - uint64_t dutfl:6; - uint64_t reserved_17_31:15; - uint64_t ioccmdfl:1; - uint64_t reserved_13_15:3; - uint64_t iocdatfl:1; - uint64_t reserved_9_11:3; - uint64_t dutresfl:1; - uint64_t reserved_5_7:3; - uint64_t vrtfl:1; - uint64_t reserved_1_3:3; - uint64_t tdffl:1; - } s; - struct cvmx_l2c_bst_s cn63xx; - struct cvmx_l2c_bst_s cn63xxp1; -}; +#define CVMX_L2C_BST0 \ + CVMX_ADD_IO_SEG(0x00011800800007F8ull) +#define CVMX_L2C_BST1 \ + CVMX_ADD_IO_SEG(0x00011800800007F0ull) +#define CVMX_L2C_BST2 \ + CVMX_ADD_IO_SEG(0x00011800800007E8ull) +#define CVMX_L2C_CFG \ + CVMX_ADD_IO_SEG(0x0001180080000000ull) +#define CVMX_L2C_DBG \ + CVMX_ADD_IO_SEG(0x0001180080000030ull) +#define CVMX_L2C_DUT \ + CVMX_ADD_IO_SEG(0x0001180080000050ull) +#define CVMX_L2C_GRPWRR0 \ + CVMX_ADD_IO_SEG(0x00011800800000C8ull) +#define CVMX_L2C_GRPWRR1 \ + CVMX_ADD_IO_SEG(0x00011800800000D0ull) +#define CVMX_L2C_INT_EN \ + CVMX_ADD_IO_SEG(0x0001180080000100ull) +#define CVMX_L2C_INT_STAT \ + CVMX_ADD_IO_SEG(0x00011800800000F8ull) +#define CVMX_L2C_LCKBASE \ + CVMX_ADD_IO_SEG(0x0001180080000058ull) +#define CVMX_L2C_LCKOFF \ + CVMX_ADD_IO_SEG(0x0001180080000060ull) +#define CVMX_L2C_LFB0 \ + CVMX_ADD_IO_SEG(0x0001180080000038ull) +#define CVMX_L2C_LFB1 \ + CVMX_ADD_IO_SEG(0x0001180080000040ull) +#define CVMX_L2C_LFB2 \ + CVMX_ADD_IO_SEG(0x0001180080000048ull) +#define CVMX_L2C_LFB3 \ + CVMX_ADD_IO_SEG(0x00011800800000B8ull) +#define CVMX_L2C_OOB \ + CVMX_ADD_IO_SEG(0x00011800800000D8ull) +#define CVMX_L2C_OOB1 \ + CVMX_ADD_IO_SEG(0x00011800800000E0ull) +#define CVMX_L2C_OOB2 \ + CVMX_ADD_IO_SEG(0x00011800800000E8ull) +#define CVMX_L2C_OOB3 \ + CVMX_ADD_IO_SEG(0x00011800800000F0ull) +#define CVMX_L2C_PFC0 \ + CVMX_ADD_IO_SEG(0x0001180080000098ull) +#define CVMX_L2C_PFC1 \ + CVMX_ADD_IO_SEG(0x00011800800000A0ull) +#define CVMX_L2C_PFC2 \ + CVMX_ADD_IO_SEG(0x00011800800000A8ull) +#define CVMX_L2C_PFC3 \ + CVMX_ADD_IO_SEG(0x00011800800000B0ull) +#define CVMX_L2C_PFCTL \ + CVMX_ADD_IO_SEG(0x0001180080000090ull) +#define CVMX_L2C_PFCX(offset) \ + CVMX_ADD_IO_SEG(0x0001180080000098ull + (((offset) & 3) * 8)) +#define CVMX_L2C_PPGRP \ + CVMX_ADD_IO_SEG(0x00011800800000C0ull) +#define CVMX_L2C_SPAR0 \ + CVMX_ADD_IO_SEG(0x0001180080000068ull) +#define CVMX_L2C_SPAR1 \ + CVMX_ADD_IO_SEG(0x0001180080000070ull) +#define CVMX_L2C_SPAR2 \ + CVMX_ADD_IO_SEG(0x0001180080000078ull) +#define CVMX_L2C_SPAR3 \ + CVMX_ADD_IO_SEG(0x0001180080000080ull) +#define CVMX_L2C_SPAR4 \ + CVMX_ADD_IO_SEG(0x0001180080000088ull) union cvmx_l2c_bst0 { uint64_t u64; @@ -296,48 +253,6 @@ union cvmx_l2c_bst2 { struct cvmx_l2c_bst2_cn56xx cn58xxp1; }; -union cvmx_l2c_bst_memx { - uint64_t u64; - struct cvmx_l2c_bst_memx_s { - uint64_t start_bist:1; - uint64_t clear_bist:1; - uint64_t reserved_5_61:57; - uint64_t rdffl:1; - uint64_t vbffl:4; - } s; - struct cvmx_l2c_bst_memx_s cn63xx; - struct cvmx_l2c_bst_memx_s cn63xxp1; -}; - -union cvmx_l2c_bst_tdtx { - uint64_t u64; - struct cvmx_l2c_bst_tdtx_s { - uint64_t reserved_32_63:32; - uint64_t fbfrspfl:8; - uint64_t sbffl:8; - uint64_t fbffl:8; - uint64_t l2dfl:8; - } s; - struct cvmx_l2c_bst_tdtx_s cn63xx; - struct cvmx_l2c_bst_tdtx_cn63xxp1 { - uint64_t reserved_24_63:40; - uint64_t sbffl:8; - uint64_t fbffl:8; - uint64_t l2dfl:8; - } cn63xxp1; -}; - -union cvmx_l2c_bst_ttgx { - uint64_t u64; - struct cvmx_l2c_bst_ttgx_s { - uint64_t reserved_17_63:47; - uint64_t lrufl:1; - uint64_t tagfl:16; - } s; - struct cvmx_l2c_bst_ttgx_s cn63xx; - struct cvmx_l2c_bst_ttgx_s cn63xxp1; -}; - union cvmx_l2c_cfg { uint64_t u64; struct cvmx_l2c_cfg_s { @@ -418,49 +333,6 @@ union cvmx_l2c_cfg { } cn58xxp1; }; -union cvmx_l2c_cop0_mapx { - uint64_t u64; - struct cvmx_l2c_cop0_mapx_s { - uint64_t data:64; - } s; - struct cvmx_l2c_cop0_mapx_s cn63xx; - struct cvmx_l2c_cop0_mapx_s cn63xxp1; -}; - -union cvmx_l2c_ctl { - uint64_t u64; - struct cvmx_l2c_ctl_s { - uint64_t reserved_28_63:36; - uint64_t disstgl2i:1; - uint64_t l2dfsbe:1; - uint64_t l2dfdbe:1; - uint64_t discclk:1; - uint64_t maxvab:4; - uint64_t maxlfb:4; - uint64_t rsp_arb_mode:1; - uint64_t xmc_arb_mode:1; - uint64_t ef_ena:1; - uint64_t ef_cnt:7; - uint64_t vab_thresh:4; - uint64_t disecc:1; - uint64_t disidxalias:1; - } s; - struct cvmx_l2c_ctl_s cn63xx; - struct cvmx_l2c_ctl_cn63xxp1 { - uint64_t reserved_25_63:39; - uint64_t discclk:1; - uint64_t maxvab:4; - uint64_t maxlfb:4; - uint64_t rsp_arb_mode:1; - uint64_t xmc_arb_mode:1; - uint64_t ef_ena:1; - uint64_t ef_cnt:7; - uint64_t vab_thresh:4; - uint64_t disecc:1; - uint64_t disidxalias:1; - } cn63xxp1; -}; - union cvmx_l2c_dbg { uint64_t u64; struct cvmx_l2c_dbg_s { @@ -477,9 +349,7 @@ union cvmx_l2c_dbg { uint64_t reserved_13_63:51; uint64_t lfb_enum:2; uint64_t lfb_dmp:1; - uint64_t reserved_7_9:3; - uint64_t ppnum:1; - uint64_t reserved_5_5:1; + uint64_t reserved_5_9:5; uint64_t set:2; uint64_t finv:1; uint64_t l2d:1; @@ -550,79 +420,6 @@ union cvmx_l2c_dut { struct cvmx_l2c_dut_s cn58xxp1; }; -union cvmx_l2c_dut_mapx { - uint64_t u64; - struct cvmx_l2c_dut_mapx_s { - uint64_t reserved_38_63:26; - uint64_t tag:28; - uint64_t reserved_1_9:9; - uint64_t valid:1; - } s; - struct cvmx_l2c_dut_mapx_s cn63xx; - struct cvmx_l2c_dut_mapx_s cn63xxp1; -}; - -union cvmx_l2c_err_tdtx { - uint64_t u64; - struct cvmx_l2c_err_tdtx_s { - uint64_t dbe:1; - uint64_t sbe:1; - uint64_t vdbe:1; - uint64_t vsbe:1; - uint64_t syn:10; - uint64_t reserved_21_49:29; - uint64_t wayidx:17; - uint64_t reserved_2_3:2; - uint64_t type:2; - } s; - struct cvmx_l2c_err_tdtx_s cn63xx; - struct cvmx_l2c_err_tdtx_s cn63xxp1; -}; - -union cvmx_l2c_err_ttgx { - uint64_t u64; - struct cvmx_l2c_err_ttgx_s { - uint64_t dbe:1; - uint64_t sbe:1; - uint64_t noway:1; - uint64_t reserved_56_60:5; - uint64_t syn:6; - uint64_t reserved_21_49:29; - uint64_t wayidx:14; - uint64_t reserved_2_6:5; - uint64_t type:2; - } s; - struct cvmx_l2c_err_ttgx_s cn63xx; - struct cvmx_l2c_err_ttgx_s cn63xxp1; -}; - -union cvmx_l2c_err_vbfx { - uint64_t u64; - struct cvmx_l2c_err_vbfx_s { - uint64_t reserved_62_63:2; - uint64_t vdbe:1; - uint64_t vsbe:1; - uint64_t vsyn:10; - uint64_t reserved_2_49:48; - uint64_t type:2; - } s; - struct cvmx_l2c_err_vbfx_s cn63xx; - struct cvmx_l2c_err_vbfx_s cn63xxp1; -}; - -union cvmx_l2c_err_xmc { - uint64_t u64; - struct cvmx_l2c_err_xmc_s { - uint64_t cmd:6; - uint64_t reserved_52_57:6; - uint64_t sid:4; - uint64_t reserved_38_47:10; - uint64_t addr:38; - } s; - struct cvmx_l2c_err_xmc_s cn63xx; - struct cvmx_l2c_err_xmc_s cn63xxp1; -}; - union cvmx_l2c_grpwrr0 { uint64_t u64; struct cvmx_l2c_grpwrr0_s { @@ -667,60 +464,6 @@ union cvmx_l2c_int_en { struct cvmx_l2c_int_en_s cn56xxp1; }; -union cvmx_l2c_int_ena { - uint64_t u64; - struct cvmx_l2c_int_ena_s { - uint64_t reserved_8_63:56; - uint64_t bigrd:1; - uint64_t bigwr:1; - uint64_t vrtpe:1; - uint64_t vrtadrng:1; - uint64_t vrtidrng:1; - uint64_t vrtwr:1; - uint64_t holewr:1; - uint64_t holerd:1; - } s; - struct cvmx_l2c_int_ena_s cn63xx; - struct cvmx_l2c_int_ena_cn63xxp1 { - uint64_t reserved_6_63:58; - uint64_t vrtpe:1; - uint64_t vrtadrng:1; - uint64_t vrtidrng:1; - uint64_t vrtwr:1; - uint64_t holewr:1; - uint64_t holerd:1; - } cn63xxp1; -}; - -union cvmx_l2c_int_reg { - uint64_t u64; - struct cvmx_l2c_int_reg_s { - uint64_t reserved_17_63:47; - uint64_t tad0:1; - uint64_t reserved_8_15:8; - uint64_t bigrd:1; - uint64_t bigwr:1; - uint64_t vrtpe:1; - uint64_t vrtadrng:1; - uint64_t vrtidrng:1; - uint64_t vrtwr:1; - uint64_t holewr:1; - uint64_t holerd:1; - } s; - struct cvmx_l2c_int_reg_s cn63xx; - struct cvmx_l2c_int_reg_cn63xxp1 { - uint64_t reserved_17_63:47; - uint64_t tad0:1; - uint64_t reserved_6_15:10; - uint64_t vrtpe:1; - uint64_t vrtadrng:1; - uint64_t vrtidrng:1; - uint64_t vrtwr:1; - uint64_t holewr:1; - uint64_t holerd:1; - } cn63xxp1; -}; - union cvmx_l2c_int_stat { uint64_t u64; struct cvmx_l2c_int_stat_s { @@ -741,24 +484,6 @@ union cvmx_l2c_int_stat { struct cvmx_l2c_int_stat_s cn56xxp1; }; -union cvmx_l2c_iocx_pfc { - uint64_t u64; - struct cvmx_l2c_iocx_pfc_s { - uint64_t count:64; - } s; - struct cvmx_l2c_iocx_pfc_s cn63xx; - struct cvmx_l2c_iocx_pfc_s cn63xxp1; -}; - -union cvmx_l2c_iorx_pfc { - uint64_t u64; - struct cvmx_l2c_iorx_pfc_s { - uint64_t count:64; - } s; - struct cvmx_l2c_iorx_pfc_s cn63xx; - struct cvmx_l2c_iorx_pfc_s cn63xxp1; -}; - union cvmx_l2c_lckbase { uint64_t u64; struct cvmx_l2c_lckbase_s { @@ -1130,59 +855,6 @@ union cvmx_l2c_ppgrp { struct cvmx_l2c_ppgrp_s cn56xxp1; }; -union cvmx_l2c_qos_iobx { - uint64_t u64; - struct cvmx_l2c_qos_iobx_s { - uint64_t reserved_6_63:58; - uint64_t dwblvl:2; - uint64_t reserved_2_3:2; - uint64_t lvl:2; - } s; - struct cvmx_l2c_qos_iobx_s cn63xx; - struct cvmx_l2c_qos_iobx_s cn63xxp1; -}; - -union cvmx_l2c_qos_ppx { - uint64_t u64; - struct cvmx_l2c_qos_ppx_s { - uint64_t reserved_2_63:62; - uint64_t lvl:2; - } s; - struct cvmx_l2c_qos_ppx_s cn63xx; - struct cvmx_l2c_qos_ppx_s cn63xxp1; -}; - -union cvmx_l2c_qos_wgt { - uint64_t u64; - struct cvmx_l2c_qos_wgt_s { - uint64_t reserved_32_63:32; - uint64_t wgt3:8; - uint64_t wgt2:8; - uint64_t wgt1:8; - uint64_t wgt0:8; - } s; - struct cvmx_l2c_qos_wgt_s cn63xx; - struct cvmx_l2c_qos_wgt_s cn63xxp1; -}; - -union cvmx_l2c_rscx_pfc { - uint64_t u64; - struct cvmx_l2c_rscx_pfc_s { - uint64_t count:64; - } s; - struct cvmx_l2c_rscx_pfc_s cn63xx; - struct cvmx_l2c_rscx_pfc_s cn63xxp1; -}; - -union cvmx_l2c_rsdx_pfc { - uint64_t u64; - struct cvmx_l2c_rsdx_pfc_s { - uint64_t count:64; - } s; - struct cvmx_l2c_rsdx_pfc_s cn63xx; - struct cvmx_l2c_rsdx_pfc_s cn63xxp1; -}; - union cvmx_l2c_spar0 { uint64_t u64; struct cvmx_l2c_spar0_s { @@ -1288,282 +960,4 @@ union cvmx_l2c_spar4 { struct cvmx_l2c_spar4_s cn58xxp1; }; -union cvmx_l2c_tadx_ecc0 { - uint64_t u64; - struct cvmx_l2c_tadx_ecc0_s { - uint64_t reserved_58_63:6; - uint64_t ow3ecc:10; - uint64_t reserved_42_47:6; - uint64_t ow2ecc:10; - uint64_t reserved_26_31:6; - uint64_t ow1ecc:10; - uint64_t reserved_10_15:6; - uint64_t ow0ecc:10; - } s; - struct cvmx_l2c_tadx_ecc0_s cn63xx; - struct cvmx_l2c_tadx_ecc0_s cn63xxp1; -}; - -union cvmx_l2c_tadx_ecc1 { - uint64_t u64; - struct cvmx_l2c_tadx_ecc1_s { - uint64_t reserved_58_63:6; - uint64_t ow7ecc:10; - uint64_t reserved_42_47:6; - uint64_t ow6ecc:10; - uint64_t reserved_26_31:6; - uint64_t ow5ecc:10; - uint64_t reserved_10_15:6; - uint64_t ow4ecc:10; - } s; - struct cvmx_l2c_tadx_ecc1_s cn63xx; - struct cvmx_l2c_tadx_ecc1_s cn63xxp1; -}; - -union cvmx_l2c_tadx_ien { - uint64_t u64; - struct cvmx_l2c_tadx_ien_s { - uint64_t reserved_9_63:55; - uint64_t wrdislmc:1; - uint64_t rddislmc:1; - uint64_t noway:1; - uint64_t vbfdbe:1; - uint64_t vbfsbe:1; - uint64_t tagdbe:1; - uint64_t tagsbe:1; - uint64_t l2ddbe:1; - uint64_t l2dsbe:1; - } s; - struct cvmx_l2c_tadx_ien_s cn63xx; - struct cvmx_l2c_tadx_ien_cn63xxp1 { - uint64_t reserved_7_63:57; - uint64_t noway:1; - uint64_t vbfdbe:1; - uint64_t vbfsbe:1; - uint64_t tagdbe:1; - uint64_t tagsbe:1; - uint64_t l2ddbe:1; - uint64_t l2dsbe:1; - } cn63xxp1; -}; - -union cvmx_l2c_tadx_int { - uint64_t u64; - struct cvmx_l2c_tadx_int_s { - uint64_t reserved_9_63:55; - uint64_t wrdislmc:1; - uint64_t rddislmc:1; - uint64_t noway:1; - uint64_t vbfdbe:1; - uint64_t vbfsbe:1; - uint64_t tagdbe:1; - uint64_t tagsbe:1; - uint64_t l2ddbe:1; - uint64_t l2dsbe:1; - } s; - struct cvmx_l2c_tadx_int_s cn63xx; -}; - -union cvmx_l2c_tadx_pfc0 { - uint64_t u64; - struct cvmx_l2c_tadx_pfc0_s { - uint64_t count:64; - } s; - struct cvmx_l2c_tadx_pfc0_s cn63xx; - struct cvmx_l2c_tadx_pfc0_s cn63xxp1; -}; - -union cvmx_l2c_tadx_pfc1 { - uint64_t u64; - struct cvmx_l2c_tadx_pfc1_s { - uint64_t count:64; - } s; - struct cvmx_l2c_tadx_pfc1_s cn63xx; - struct cvmx_l2c_tadx_pfc1_s cn63xxp1; -}; - -union cvmx_l2c_tadx_pfc2 { - uint64_t u64; - struct cvmx_l2c_tadx_pfc2_s { - uint64_t count:64; - } s; - struct cvmx_l2c_tadx_pfc2_s cn63xx; - struct cvmx_l2c_tadx_pfc2_s cn63xxp1; -}; - -union cvmx_l2c_tadx_pfc3 { - uint64_t u64; - struct cvmx_l2c_tadx_pfc3_s { - uint64_t count:64; - } s; - struct cvmx_l2c_tadx_pfc3_s cn63xx; - struct cvmx_l2c_tadx_pfc3_s cn63xxp1; -}; - -union cvmx_l2c_tadx_prf { - uint64_t u64; - struct cvmx_l2c_tadx_prf_s { - uint64_t reserved_32_63:32; - uint64_t cnt3sel:8; - uint64_t cnt2sel:8; - uint64_t cnt1sel:8; - uint64_t cnt0sel:8; - } s; - struct cvmx_l2c_tadx_prf_s cn63xx; - struct cvmx_l2c_tadx_prf_s cn63xxp1; -}; - -union cvmx_l2c_tadx_tag { - uint64_t u64; - struct cvmx_l2c_tadx_tag_s { - uint64_t reserved_46_63:18; - uint64_t ecc:6; - uint64_t reserved_36_39:4; - uint64_t tag:19; - uint64_t reserved_4_16:13; - uint64_t use:1; - uint64_t valid:1; - uint64_t dirty:1; - uint64_t lock:1; - } s; - struct cvmx_l2c_tadx_tag_s cn63xx; - struct cvmx_l2c_tadx_tag_s cn63xxp1; -}; - -union cvmx_l2c_ver_id { - uint64_t u64; - struct cvmx_l2c_ver_id_s { - uint64_t mask:64; - } s; - struct cvmx_l2c_ver_id_s cn63xx; - struct cvmx_l2c_ver_id_s cn63xxp1; -}; - -union cvmx_l2c_ver_iob { - uint64_t u64; - struct cvmx_l2c_ver_iob_s { - uint64_t reserved_1_63:63; - uint64_t mask:1; - } s; - struct cvmx_l2c_ver_iob_s cn63xx; - struct cvmx_l2c_ver_iob_s cn63xxp1; -}; - -union cvmx_l2c_ver_msc { - uint64_t u64; - struct cvmx_l2c_ver_msc_s { - uint64_t reserved_2_63:62; - uint64_t invl2:1; - uint64_t dwb:1; - } s; - struct cvmx_l2c_ver_msc_s cn63xx; -}; - -union cvmx_l2c_ver_pp { - uint64_t u64; - struct cvmx_l2c_ver_pp_s { - uint64_t reserved_6_63:58; - uint64_t mask:6; - } s; - struct cvmx_l2c_ver_pp_s cn63xx; - struct cvmx_l2c_ver_pp_s cn63xxp1; -}; - -union cvmx_l2c_virtid_iobx { - uint64_t u64; - struct cvmx_l2c_virtid_iobx_s { - uint64_t reserved_14_63:50; - uint64_t dwbid:6; - uint64_t reserved_6_7:2; - uint64_t id:6; - } s; - struct cvmx_l2c_virtid_iobx_s cn63xx; - struct cvmx_l2c_virtid_iobx_s cn63xxp1; -}; - -union cvmx_l2c_virtid_ppx { - uint64_t u64; - struct cvmx_l2c_virtid_ppx_s { - uint64_t reserved_6_63:58; - uint64_t id:6; - } s; - struct cvmx_l2c_virtid_ppx_s cn63xx; - struct cvmx_l2c_virtid_ppx_s cn63xxp1; -}; - -union cvmx_l2c_vrt_ctl { - uint64_t u64; - struct cvmx_l2c_vrt_ctl_s { - uint64_t reserved_9_63:55; - uint64_t ooberr:1; - uint64_t reserved_7_7:1; - uint64_t memsz:3; - uint64_t numid:3; - uint64_t enable:1; - } s; - struct cvmx_l2c_vrt_ctl_s cn63xx; - struct cvmx_l2c_vrt_ctl_s cn63xxp1; -}; - -union cvmx_l2c_vrt_memx { - uint64_t u64; - struct cvmx_l2c_vrt_memx_s { - uint64_t reserved_36_63:28; - uint64_t parity:4; - uint64_t data:32; - } s; - struct cvmx_l2c_vrt_memx_s cn63xx; - struct cvmx_l2c_vrt_memx_s cn63xxp1; -}; - -union cvmx_l2c_wpar_iobx { - uint64_t u64; - struct cvmx_l2c_wpar_iobx_s { - uint64_t reserved_16_63:48; - uint64_t mask:16; - } s; - struct cvmx_l2c_wpar_iobx_s cn63xx; - struct cvmx_l2c_wpar_iobx_s cn63xxp1; -}; - -union cvmx_l2c_wpar_ppx { - uint64_t u64; - struct cvmx_l2c_wpar_ppx_s { - uint64_t reserved_16_63:48; - uint64_t mask:16; - } s; - struct cvmx_l2c_wpar_ppx_s cn63xx; - struct cvmx_l2c_wpar_ppx_s cn63xxp1; -}; - -union cvmx_l2c_xmcx_pfc { - uint64_t u64; - struct cvmx_l2c_xmcx_pfc_s { - uint64_t count:64; - } s; - struct cvmx_l2c_xmcx_pfc_s cn63xx; - struct cvmx_l2c_xmcx_pfc_s cn63xxp1; -}; - -union cvmx_l2c_xmc_cmd { - uint64_t u64; - struct cvmx_l2c_xmc_cmd_s { - uint64_t inuse:1; - uint64_t cmd:6; - uint64_t reserved_38_56:19; - uint64_t addr:38; - } s; - struct cvmx_l2c_xmc_cmd_s cn63xx; - struct cvmx_l2c_xmc_cmd_s cn63xxp1; -}; - -union cvmx_l2c_xmdx_pfc { - uint64_t u64; - struct cvmx_l2c_xmdx_pfc_s { - uint64_t count:64; - } s; - struct cvmx_l2c_xmdx_pfc_s cn63xx; - struct cvmx_l2c_xmdx_pfc_s cn63xxp1; -}; - #endif diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-l2c.h b/trunk/arch/mips/include/asm/octeon/cvmx-l2c.h index 0b32c5b118e2..2a8c0902ea50 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-l2c.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-l2c.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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,6 +26,7 @@ ***********************license end**************************************/ /* + * * Interface to the Level 2 Cache (L2C) control, measurement, and debugging * facilities. */ @@ -33,126 +34,93 @@ #ifndef __CVMX_L2C_H__ #define __CVMX_L2C_H__ -#define CVMX_L2_ASSOC cvmx_l2c_get_num_assoc() /* Deprecated macro, use function */ -#define CVMX_L2_SET_BITS cvmx_l2c_get_set_bits() /* Deprecated macro, use function */ -#define CVMX_L2_SETS cvmx_l2c_get_num_sets() /* Deprecated macro, use function */ +/* Deprecated macro, use function */ +#define CVMX_L2_ASSOC cvmx_l2c_get_num_assoc() + +/* Deprecated macro, use function */ +#define CVMX_L2_SET_BITS cvmx_l2c_get_set_bits() +/* Deprecated macro, use function */ +#define CVMX_L2_SETS cvmx_l2c_get_num_sets() #define CVMX_L2C_IDX_ADDR_SHIFT 7 /* based on 128 byte cache line size */ #define CVMX_L2C_IDX_MASK (cvmx_l2c_get_num_sets() - 1) /* Defines for index aliasing computations */ -#define CVMX_L2C_TAG_ADDR_ALIAS_SHIFT (CVMX_L2C_IDX_ADDR_SHIFT + cvmx_l2c_get_set_bits()) -#define CVMX_L2C_ALIAS_MASK (CVMX_L2C_IDX_MASK << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) -#define CVMX_L2C_MEMBANK_SELECT_SIZE 4096 +#define CVMX_L2C_TAG_ADDR_ALIAS_SHIFT \ + (CVMX_L2C_IDX_ADDR_SHIFT + cvmx_l2c_get_set_bits()) -/* Defines for Virtualizations, valid only from Octeon II onwards. */ -#define CVMX_L2C_VRT_MAX_VIRTID_ALLOWED ((OCTEON_IS_MODEL(OCTEON_CN63XX)) ? 64 : 0) -#define CVMX_L2C_VRT_MAX_MEMSZ_ALLOWED ((OCTEON_IS_MODEL(OCTEON_CN63XX)) ? 32 : 0) +#define CVMX_L2C_ALIAS_MASK \ + (CVMX_L2C_IDX_MASK << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) union cvmx_l2c_tag { uint64_t u64; struct { uint64_t reserved:28; - 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:32; /* Phys mem (not all bits valid) */ } s; }; -/* Number of L2C Tag-and-data sections (TADs) that are connected to LMC. */ -#define CVMX_L2C_TADS 1 - /* L2C Performance Counter events. */ enum cvmx_l2c_event { - CVMX_L2C_EVENT_CYCLES = 0, - CVMX_L2C_EVENT_INSTRUCTION_MISS = 1, - CVMX_L2C_EVENT_INSTRUCTION_HIT = 2, - CVMX_L2C_EVENT_DATA_MISS = 3, - CVMX_L2C_EVENT_DATA_HIT = 4, - CVMX_L2C_EVENT_MISS = 5, - CVMX_L2C_EVENT_HIT = 6, - CVMX_L2C_EVENT_VICTIM_HIT = 7, - CVMX_L2C_EVENT_INDEX_CONFLICT = 8, - CVMX_L2C_EVENT_TAG_PROBE = 9, - CVMX_L2C_EVENT_TAG_UPDATE = 10, - CVMX_L2C_EVENT_TAG_COMPLETE = 11, - CVMX_L2C_EVENT_TAG_DIRTY = 12, - CVMX_L2C_EVENT_DATA_STORE_NOP = 13, - CVMX_L2C_EVENT_DATA_STORE_READ = 14, + CVMX_L2C_EVENT_CYCLES = 0, + CVMX_L2C_EVENT_INSTRUCTION_MISS = 1, + CVMX_L2C_EVENT_INSTRUCTION_HIT = 2, + CVMX_L2C_EVENT_DATA_MISS = 3, + CVMX_L2C_EVENT_DATA_HIT = 4, + CVMX_L2C_EVENT_MISS = 5, + CVMX_L2C_EVENT_HIT = 6, + CVMX_L2C_EVENT_VICTIM_HIT = 7, + CVMX_L2C_EVENT_INDEX_CONFLICT = 8, + CVMX_L2C_EVENT_TAG_PROBE = 9, + CVMX_L2C_EVENT_TAG_UPDATE = 10, + CVMX_L2C_EVENT_TAG_COMPLETE = 11, + CVMX_L2C_EVENT_TAG_DIRTY = 12, + CVMX_L2C_EVENT_DATA_STORE_NOP = 13, + CVMX_L2C_EVENT_DATA_STORE_READ = 14, CVMX_L2C_EVENT_DATA_STORE_WRITE = 15, - CVMX_L2C_EVENT_FILL_DATA_VALID = 16, - CVMX_L2C_EVENT_WRITE_REQUEST = 17, - CVMX_L2C_EVENT_READ_REQUEST = 18, + CVMX_L2C_EVENT_FILL_DATA_VALID = 16, + CVMX_L2C_EVENT_WRITE_REQUEST = 17, + CVMX_L2C_EVENT_READ_REQUEST = 18, CVMX_L2C_EVENT_WRITE_DATA_VALID = 19, - CVMX_L2C_EVENT_XMC_NOP = 20, - CVMX_L2C_EVENT_XMC_LDT = 21, - CVMX_L2C_EVENT_XMC_LDI = 22, - CVMX_L2C_EVENT_XMC_LDD = 23, - CVMX_L2C_EVENT_XMC_STF = 24, - CVMX_L2C_EVENT_XMC_STT = 25, - CVMX_L2C_EVENT_XMC_STP = 26, - CVMX_L2C_EVENT_XMC_STC = 27, - CVMX_L2C_EVENT_XMC_DWB = 28, - CVMX_L2C_EVENT_XMC_PL2 = 29, - CVMX_L2C_EVENT_XMC_PSL1 = 30, - CVMX_L2C_EVENT_XMC_IOBLD = 31, - CVMX_L2C_EVENT_XMC_IOBST = 32, - CVMX_L2C_EVENT_XMC_IOBDMA = 33, - CVMX_L2C_EVENT_XMC_IOBRSP = 34, - CVMX_L2C_EVENT_XMC_BUS_VALID = 35, - CVMX_L2C_EVENT_XMC_MEM_DATA = 36, - CVMX_L2C_EVENT_XMC_REFL_DATA = 37, - CVMX_L2C_EVENT_XMC_IOBRSP_DATA = 38, - CVMX_L2C_EVENT_RSC_NOP = 39, - CVMX_L2C_EVENT_RSC_STDN = 40, - CVMX_L2C_EVENT_RSC_FILL = 41, - CVMX_L2C_EVENT_RSC_REFL = 42, - CVMX_L2C_EVENT_RSC_STIN = 43, - CVMX_L2C_EVENT_RSC_SCIN = 44, - CVMX_L2C_EVENT_RSC_SCFL = 45, - CVMX_L2C_EVENT_RSC_SCDN = 46, - CVMX_L2C_EVENT_RSC_DATA_VALID = 47, - CVMX_L2C_EVENT_RSC_VALID_FILL = 48, - CVMX_L2C_EVENT_RSC_VALID_STRSP = 49, - CVMX_L2C_EVENT_RSC_VALID_REFL = 50, - CVMX_L2C_EVENT_LRF_REQ = 51, - CVMX_L2C_EVENT_DT_RD_ALLOC = 52, - CVMX_L2C_EVENT_DT_WR_INVAL = 53, - CVMX_L2C_EVENT_MAX -}; - -/* L2C Performance Counter events for Octeon2. */ -enum cvmx_l2c_tad_event { - CVMX_L2C_TAD_EVENT_NONE = 0, - CVMX_L2C_TAD_EVENT_TAG_HIT = 1, - CVMX_L2C_TAD_EVENT_TAG_MISS = 2, - CVMX_L2C_TAD_EVENT_TAG_NOALLOC = 3, - CVMX_L2C_TAD_EVENT_TAG_VICTIM = 4, - CVMX_L2C_TAD_EVENT_SC_FAIL = 5, - CVMX_L2C_TAD_EVENT_SC_PASS = 6, - CVMX_L2C_TAD_EVENT_LFB_VALID = 7, - CVMX_L2C_TAD_EVENT_LFB_WAIT_LFB = 8, - CVMX_L2C_TAD_EVENT_LFB_WAIT_VAB = 9, - CVMX_L2C_TAD_EVENT_QUAD0_INDEX = 128, - CVMX_L2C_TAD_EVENT_QUAD0_READ = 129, - CVMX_L2C_TAD_EVENT_QUAD0_BANK = 130, - CVMX_L2C_TAD_EVENT_QUAD0_WDAT = 131, - CVMX_L2C_TAD_EVENT_QUAD1_INDEX = 144, - CVMX_L2C_TAD_EVENT_QUAD1_READ = 145, - CVMX_L2C_TAD_EVENT_QUAD1_BANK = 146, - CVMX_L2C_TAD_EVENT_QUAD1_WDAT = 147, - CVMX_L2C_TAD_EVENT_QUAD2_INDEX = 160, - CVMX_L2C_TAD_EVENT_QUAD2_READ = 161, - CVMX_L2C_TAD_EVENT_QUAD2_BANK = 162, - CVMX_L2C_TAD_EVENT_QUAD2_WDAT = 163, - CVMX_L2C_TAD_EVENT_QUAD3_INDEX = 176, - CVMX_L2C_TAD_EVENT_QUAD3_READ = 177, - CVMX_L2C_TAD_EVENT_QUAD3_BANK = 178, - CVMX_L2C_TAD_EVENT_QUAD3_WDAT = 179, - CVMX_L2C_TAD_EVENT_MAX + CVMX_L2C_EVENT_XMC_NOP = 20, + CVMX_L2C_EVENT_XMC_LDT = 21, + CVMX_L2C_EVENT_XMC_LDI = 22, + CVMX_L2C_EVENT_XMC_LDD = 23, + CVMX_L2C_EVENT_XMC_STF = 24, + CVMX_L2C_EVENT_XMC_STT = 25, + CVMX_L2C_EVENT_XMC_STP = 26, + CVMX_L2C_EVENT_XMC_STC = 27, + CVMX_L2C_EVENT_XMC_DWB = 28, + CVMX_L2C_EVENT_XMC_PL2 = 29, + CVMX_L2C_EVENT_XMC_PSL1 = 30, + CVMX_L2C_EVENT_XMC_IOBLD = 31, + CVMX_L2C_EVENT_XMC_IOBST = 32, + CVMX_L2C_EVENT_XMC_IOBDMA = 33, + CVMX_L2C_EVENT_XMC_IOBRSP = 34, + CVMX_L2C_EVENT_XMC_BUS_VALID = 35, + CVMX_L2C_EVENT_XMC_MEM_DATA = 36, + CVMX_L2C_EVENT_XMC_REFL_DATA = 37, + CVMX_L2C_EVENT_XMC_IOBRSP_DATA = 38, + CVMX_L2C_EVENT_RSC_NOP = 39, + CVMX_L2C_EVENT_RSC_STDN = 40, + CVMX_L2C_EVENT_RSC_FILL = 41, + CVMX_L2C_EVENT_RSC_REFL = 42, + CVMX_L2C_EVENT_RSC_STIN = 43, + CVMX_L2C_EVENT_RSC_SCIN = 44, + CVMX_L2C_EVENT_RSC_SCFL = 45, + CVMX_L2C_EVENT_RSC_SCDN = 46, + CVMX_L2C_EVENT_RSC_DATA_VALID = 47, + CVMX_L2C_EVENT_RSC_VALID_FILL = 48, + CVMX_L2C_EVENT_RSC_VALID_STRSP = 49, + CVMX_L2C_EVENT_RSC_VALID_REFL = 50, + CVMX_L2C_EVENT_LRF_REQ = 51, + CVMX_L2C_EVENT_DT_RD_ALLOC = 52, + CVMX_L2C_EVENT_DT_WR_INVAL = 53 }; /** @@ -164,10 +132,10 @@ enum cvmx_l2c_tad_event { * @clear_on_read: When asserted, any read of the performance counter * clears the counter. * - * @note The routine does not clear the counter. + * The routine does not clear the counter. */ -void cvmx_l2c_config_perf(uint32_t counter, enum cvmx_l2c_event event, uint32_t clear_on_read); - +void cvmx_l2c_config_perf(uint32_t counter, + enum cvmx_l2c_event event, uint32_t clear_on_read); /** * Read the given L2 Cache performance counter. The counter must be configured * before reading, but this routine does not enforce this requirement. @@ -192,18 +160,18 @@ int cvmx_l2c_get_core_way_partition(uint32_t core); /** * Partitions the L2 cache for a core * - * @core: The core that the partitioning applies to. - * @mask: The partitioning of the ways expressed as a binary - * mask. A 0 bit allows the core to evict cache lines from - * a way, while a 1 bit blocks the core from evicting any - * lines from that way. There must be at least one allowed - * way (0 bit) in the mask. + * @core: The core that the partitioning applies to. * - - * @note If any ways are blocked for all cores and the HW blocks, then - * those ways will never have any cache lines evicted from them. - * All cores and the hardware blocks are free to read from all - * ways regardless of the partitioning. + * @mask: The partitioning of the ways expressed as a binary mask. A 0 + * bit allows the core to evict cache lines from a way, while a + * 1 bit blocks the core from evicting any lines from that + * way. There must be at least one allowed way (0 bit) in the + * mask. + * + * If any ways are blocked for all cores and the HW blocks, then those + * ways will never have any cache lines evicted from them. All cores + * and the hardware blocks are free to read from all ways regardless + * of the partitioning. */ int cvmx_l2c_set_core_way_partition(uint32_t core, uint32_t mask); @@ -219,21 +187,19 @@ int cvmx_l2c_get_hw_way_partition(void); /** * Partitions the L2 cache for the hardware blocks. * - * @mask: The partitioning of the ways expressed as a binary - * mask. A 0 bit allows the core to evict cache lines from - * a way, while a 1 bit blocks the core from evicting any - * lines from that way. There must be at least one allowed - * way (0 bit) in the mask. + * @mask: The partitioning of the ways expressed as a binary mask. A 0 + * bit allows the core to evict cache lines from a way, while a + * 1 bit blocks the core from evicting any lines from that + * way. There must be at least one allowed way (0 bit) in the + * mask. * - - * @note If any ways are blocked for all cores and the HW blocks, then - * those ways will never have any cache lines evicted from them. - * All cores and the hardware blocks are free to read from all - * ways regardless of the partitioning. + * If any ways are blocked for all cores and the HW blocks, then those + * ways will never have any cache lines evicted from them. All cores + * and the hardware blocks are free to read from all ways regardless + * of the partitioning. */ int cvmx_l2c_set_hw_way_partition(uint32_t mask); - /** * Locks a line in the L2 cache at the specified physical address * @@ -297,14 +263,13 @@ int cvmx_l2c_unlock_mem_region(uint64_t start, uint64_t len); */ union cvmx_l2c_tag cvmx_l2c_get_tag(uint32_t association, uint32_t index); -/* Wrapper providing a deprecated old function name */ -static inline union cvmx_l2c_tag cvmx_get_l2c_tag(uint32_t association, uint32_t index) __attribute__((deprecated)); -static inline union cvmx_l2c_tag cvmx_get_l2c_tag(uint32_t association, uint32_t index) +/* Wrapper around deprecated old function name */ +static inline union cvmx_l2c_tag cvmx_get_l2c_tag(uint32_t association, + uint32_t index) { return cvmx_l2c_get_tag(association, index); } - /** * Returns the cache index for a given physical address * diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-l2d-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-l2d-defs.h index 60543e0e77fc..d7102d455e1b 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-l2d-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-l2d-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,18 +28,30 @@ #ifndef __CVMX_L2D_DEFS_H__ #define __CVMX_L2D_DEFS_H__ -#define CVMX_L2D_BST0 (CVMX_ADD_IO_SEG(0x0001180080000780ull)) -#define CVMX_L2D_BST1 (CVMX_ADD_IO_SEG(0x0001180080000788ull)) -#define CVMX_L2D_BST2 (CVMX_ADD_IO_SEG(0x0001180080000790ull)) -#define CVMX_L2D_BST3 (CVMX_ADD_IO_SEG(0x0001180080000798ull)) -#define CVMX_L2D_ERR (CVMX_ADD_IO_SEG(0x0001180080000010ull)) -#define CVMX_L2D_FADR (CVMX_ADD_IO_SEG(0x0001180080000018ull)) -#define CVMX_L2D_FSYN0 (CVMX_ADD_IO_SEG(0x0001180080000020ull)) -#define CVMX_L2D_FSYN1 (CVMX_ADD_IO_SEG(0x0001180080000028ull)) -#define CVMX_L2D_FUS0 (CVMX_ADD_IO_SEG(0x00011800800007A0ull)) -#define CVMX_L2D_FUS1 (CVMX_ADD_IO_SEG(0x00011800800007A8ull)) -#define CVMX_L2D_FUS2 (CVMX_ADD_IO_SEG(0x00011800800007B0ull)) -#define CVMX_L2D_FUS3 (CVMX_ADD_IO_SEG(0x00011800800007B8ull)) +#define CVMX_L2D_BST0 \ + CVMX_ADD_IO_SEG(0x0001180080000780ull) +#define CVMX_L2D_BST1 \ + CVMX_ADD_IO_SEG(0x0001180080000788ull) +#define CVMX_L2D_BST2 \ + CVMX_ADD_IO_SEG(0x0001180080000790ull) +#define CVMX_L2D_BST3 \ + CVMX_ADD_IO_SEG(0x0001180080000798ull) +#define CVMX_L2D_ERR \ + CVMX_ADD_IO_SEG(0x0001180080000010ull) +#define CVMX_L2D_FADR \ + CVMX_ADD_IO_SEG(0x0001180080000018ull) +#define CVMX_L2D_FSYN0 \ + CVMX_ADD_IO_SEG(0x0001180080000020ull) +#define CVMX_L2D_FSYN1 \ + CVMX_ADD_IO_SEG(0x0001180080000028ull) +#define CVMX_L2D_FUS0 \ + CVMX_ADD_IO_SEG(0x00011800800007A0ull) +#define CVMX_L2D_FUS1 \ + CVMX_ADD_IO_SEG(0x00011800800007A8ull) +#define CVMX_L2D_FUS2 \ + CVMX_ADD_IO_SEG(0x00011800800007B0ull) +#define CVMX_L2D_FUS3 \ + CVMX_ADD_IO_SEG(0x00011800800007B8ull) union cvmx_l2d_bst0 { uint64_t u64; diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-l2t-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-l2t-defs.h index 873968f55eeb..2639a3f5ffc2 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-l2t-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-l2t-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,7 +28,8 @@ #ifndef __CVMX_L2T_DEFS_H__ #define __CVMX_L2T_DEFS_H__ -#define CVMX_L2T_ERR (CVMX_ADD_IO_SEG(0x0001180080000008ull)) +#define CVMX_L2T_ERR \ + CVMX_ADD_IO_SEG(0x0001180080000008ull) union cvmx_l2t_err { uint64_t u64; diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-led-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-led-defs.h index e25173bb8bb7..16f174a4dadf 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-led-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-led-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,19 +28,32 @@ #ifndef __CVMX_LED_DEFS_H__ #define __CVMX_LED_DEFS_H__ -#define CVMX_LED_BLINK (CVMX_ADD_IO_SEG(0x0001180000001A48ull)) -#define CVMX_LED_CLK_PHASE (CVMX_ADD_IO_SEG(0x0001180000001A08ull)) -#define CVMX_LED_CYLON (CVMX_ADD_IO_SEG(0x0001180000001AF8ull)) -#define CVMX_LED_DBG (CVMX_ADD_IO_SEG(0x0001180000001A18ull)) -#define CVMX_LED_EN (CVMX_ADD_IO_SEG(0x0001180000001A00ull)) -#define CVMX_LED_POLARITY (CVMX_ADD_IO_SEG(0x0001180000001A50ull)) -#define CVMX_LED_PRT (CVMX_ADD_IO_SEG(0x0001180000001A10ull)) -#define CVMX_LED_PRT_FMT (CVMX_ADD_IO_SEG(0x0001180000001A30ull)) -#define CVMX_LED_PRT_STATUSX(offset) (CVMX_ADD_IO_SEG(0x0001180000001A80ull) + ((offset) & 7) * 8) -#define CVMX_LED_UDD_CNTX(offset) (CVMX_ADD_IO_SEG(0x0001180000001A20ull) + ((offset) & 1) * 8) -#define CVMX_LED_UDD_DATX(offset) (CVMX_ADD_IO_SEG(0x0001180000001A38ull) + ((offset) & 1) * 8) -#define CVMX_LED_UDD_DAT_CLRX(offset) (CVMX_ADD_IO_SEG(0x0001180000001AC8ull) + ((offset) & 1) * 16) -#define CVMX_LED_UDD_DAT_SETX(offset) (CVMX_ADD_IO_SEG(0x0001180000001AC0ull) + ((offset) & 1) * 16) +#define CVMX_LED_BLINK \ + CVMX_ADD_IO_SEG(0x0001180000001A48ull) +#define CVMX_LED_CLK_PHASE \ + CVMX_ADD_IO_SEG(0x0001180000001A08ull) +#define CVMX_LED_CYLON \ + CVMX_ADD_IO_SEG(0x0001180000001AF8ull) +#define CVMX_LED_DBG \ + CVMX_ADD_IO_SEG(0x0001180000001A18ull) +#define CVMX_LED_EN \ + CVMX_ADD_IO_SEG(0x0001180000001A00ull) +#define CVMX_LED_POLARITY \ + CVMX_ADD_IO_SEG(0x0001180000001A50ull) +#define CVMX_LED_PRT \ + CVMX_ADD_IO_SEG(0x0001180000001A10ull) +#define CVMX_LED_PRT_FMT \ + CVMX_ADD_IO_SEG(0x0001180000001A30ull) +#define CVMX_LED_PRT_STATUSX(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001A80ull + (((offset) & 7) * 8)) +#define CVMX_LED_UDD_CNTX(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001A20ull + (((offset) & 1) * 8)) +#define CVMX_LED_UDD_DATX(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001A38ull + (((offset) & 1) * 8)) +#define CVMX_LED_UDD_DAT_CLRX(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001AC8ull + (((offset) & 1) * 16)) +#define CVMX_LED_UDD_DAT_SETX(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001AC0ull + (((offset) & 1) * 16)) union cvmx_led_blink { uint64_t u64; diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-mio-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-mio-defs.h index 52b14a333ad4..6555f0530988 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-mio-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-mio-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,117 +28,191 @@ #ifndef __CVMX_MIO_DEFS_H__ #define __CVMX_MIO_DEFS_H__ -#define CVMX_MIO_BOOT_BIST_STAT (CVMX_ADD_IO_SEG(0x00011800000000F8ull)) -#define CVMX_MIO_BOOT_COMP (CVMX_ADD_IO_SEG(0x00011800000000B8ull)) -#define CVMX_MIO_BOOT_DMA_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001180000000100ull) + ((offset) & 3) * 8) -#define CVMX_MIO_BOOT_DMA_INTX(offset) (CVMX_ADD_IO_SEG(0x0001180000000138ull) + ((offset) & 3) * 8) -#define CVMX_MIO_BOOT_DMA_INT_ENX(offset) (CVMX_ADD_IO_SEG(0x0001180000000150ull) + ((offset) & 3) * 8) -#define CVMX_MIO_BOOT_DMA_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001180000000120ull) + ((offset) & 3) * 8) -#define CVMX_MIO_BOOT_ERR (CVMX_ADD_IO_SEG(0x00011800000000A0ull)) -#define CVMX_MIO_BOOT_INT (CVMX_ADD_IO_SEG(0x00011800000000A8ull)) -#define CVMX_MIO_BOOT_LOC_ADR (CVMX_ADD_IO_SEG(0x0001180000000090ull)) -#define CVMX_MIO_BOOT_LOC_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001180000000080ull) + ((offset) & 1) * 8) -#define CVMX_MIO_BOOT_LOC_DAT (CVMX_ADD_IO_SEG(0x0001180000000098ull)) -#define CVMX_MIO_BOOT_PIN_DEFS (CVMX_ADD_IO_SEG(0x00011800000000C0ull)) -#define CVMX_MIO_BOOT_REG_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001180000000000ull) + ((offset) & 7) * 8) -#define CVMX_MIO_BOOT_REG_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001180000000040ull) + ((offset) & 7) * 8) -#define CVMX_MIO_BOOT_THR (CVMX_ADD_IO_SEG(0x00011800000000B0ull)) -#define CVMX_MIO_FUS_BNK_DATX(offset) (CVMX_ADD_IO_SEG(0x0001180000001520ull) + ((offset) & 3) * 8) -#define CVMX_MIO_FUS_DAT0 (CVMX_ADD_IO_SEG(0x0001180000001400ull)) -#define CVMX_MIO_FUS_DAT1 (CVMX_ADD_IO_SEG(0x0001180000001408ull)) -#define CVMX_MIO_FUS_DAT2 (CVMX_ADD_IO_SEG(0x0001180000001410ull)) -#define CVMX_MIO_FUS_DAT3 (CVMX_ADD_IO_SEG(0x0001180000001418ull)) -#define CVMX_MIO_FUS_EMA (CVMX_ADD_IO_SEG(0x0001180000001550ull)) -#define CVMX_MIO_FUS_PDF (CVMX_ADD_IO_SEG(0x0001180000001420ull)) -#define CVMX_MIO_FUS_PLL (CVMX_ADD_IO_SEG(0x0001180000001580ull)) -#define CVMX_MIO_FUS_PROG (CVMX_ADD_IO_SEG(0x0001180000001510ull)) -#define CVMX_MIO_FUS_PROG_TIMES (CVMX_ADD_IO_SEG(0x0001180000001518ull)) -#define CVMX_MIO_FUS_RCMD (CVMX_ADD_IO_SEG(0x0001180000001500ull)) -#define CVMX_MIO_FUS_READ_TIMES (CVMX_ADD_IO_SEG(0x0001180000001570ull)) -#define CVMX_MIO_FUS_REPAIR_RES0 (CVMX_ADD_IO_SEG(0x0001180000001558ull)) -#define CVMX_MIO_FUS_REPAIR_RES1 (CVMX_ADD_IO_SEG(0x0001180000001560ull)) -#define CVMX_MIO_FUS_REPAIR_RES2 (CVMX_ADD_IO_SEG(0x0001180000001568ull)) -#define CVMX_MIO_FUS_SPR_REPAIR_RES (CVMX_ADD_IO_SEG(0x0001180000001548ull)) -#define CVMX_MIO_FUS_SPR_REPAIR_SUM (CVMX_ADD_IO_SEG(0x0001180000001540ull)) -#define CVMX_MIO_FUS_UNLOCK (CVMX_ADD_IO_SEG(0x0001180000001578ull)) -#define CVMX_MIO_FUS_WADR (CVMX_ADD_IO_SEG(0x0001180000001508ull)) -#define CVMX_MIO_GPIO_COMP (CVMX_ADD_IO_SEG(0x00011800000000C8ull)) -#define CVMX_MIO_NDF_DMA_CFG (CVMX_ADD_IO_SEG(0x0001180000000168ull)) -#define CVMX_MIO_NDF_DMA_INT (CVMX_ADD_IO_SEG(0x0001180000000170ull)) -#define CVMX_MIO_NDF_DMA_INT_EN (CVMX_ADD_IO_SEG(0x0001180000000178ull)) -#define CVMX_MIO_PLL_CTL (CVMX_ADD_IO_SEG(0x0001180000001448ull)) -#define CVMX_MIO_PLL_SETTING (CVMX_ADD_IO_SEG(0x0001180000001440ull)) -#define CVMX_MIO_PTP_CLOCK_CFG (CVMX_ADD_IO_SEG(0x0001070000000F00ull)) -#define CVMX_MIO_PTP_CLOCK_COMP (CVMX_ADD_IO_SEG(0x0001070000000F18ull)) -#define CVMX_MIO_PTP_CLOCK_HI (CVMX_ADD_IO_SEG(0x0001070000000F10ull)) -#define CVMX_MIO_PTP_CLOCK_LO (CVMX_ADD_IO_SEG(0x0001070000000F08ull)) -#define CVMX_MIO_PTP_EVT_CNT (CVMX_ADD_IO_SEG(0x0001070000000F28ull)) -#define CVMX_MIO_PTP_TIMESTAMP (CVMX_ADD_IO_SEG(0x0001070000000F20ull)) -#define CVMX_MIO_RST_BOOT (CVMX_ADD_IO_SEG(0x0001180000001600ull)) -#define CVMX_MIO_RST_CFG (CVMX_ADD_IO_SEG(0x0001180000001610ull)) -#define CVMX_MIO_RST_CTLX(offset) (CVMX_ADD_IO_SEG(0x0001180000001618ull) + ((offset) & 1) * 8) -#define CVMX_MIO_RST_DELAY (CVMX_ADD_IO_SEG(0x0001180000001608ull)) -#define CVMX_MIO_RST_INT (CVMX_ADD_IO_SEG(0x0001180000001628ull)) -#define CVMX_MIO_RST_INT_EN (CVMX_ADD_IO_SEG(0x0001180000001630ull)) -#define CVMX_MIO_TWSX_INT(offset) (CVMX_ADD_IO_SEG(0x0001180000001010ull) + ((offset) & 1) * 512) -#define CVMX_MIO_TWSX_SW_TWSI(offset) (CVMX_ADD_IO_SEG(0x0001180000001000ull) + ((offset) & 1) * 512) -#define CVMX_MIO_TWSX_SW_TWSI_EXT(offset) (CVMX_ADD_IO_SEG(0x0001180000001018ull) + ((offset) & 1) * 512) -#define CVMX_MIO_TWSX_TWSI_SW(offset) (CVMX_ADD_IO_SEG(0x0001180000001008ull) + ((offset) & 1) * 512) -#define CVMX_MIO_UART2_DLH (CVMX_ADD_IO_SEG(0x0001180000000488ull)) -#define CVMX_MIO_UART2_DLL (CVMX_ADD_IO_SEG(0x0001180000000480ull)) -#define CVMX_MIO_UART2_FAR (CVMX_ADD_IO_SEG(0x0001180000000520ull)) -#define CVMX_MIO_UART2_FCR (CVMX_ADD_IO_SEG(0x0001180000000450ull)) -#define CVMX_MIO_UART2_HTX (CVMX_ADD_IO_SEG(0x0001180000000708ull)) -#define CVMX_MIO_UART2_IER (CVMX_ADD_IO_SEG(0x0001180000000408ull)) -#define CVMX_MIO_UART2_IIR (CVMX_ADD_IO_SEG(0x0001180000000410ull)) -#define CVMX_MIO_UART2_LCR (CVMX_ADD_IO_SEG(0x0001180000000418ull)) -#define CVMX_MIO_UART2_LSR (CVMX_ADD_IO_SEG(0x0001180000000428ull)) -#define CVMX_MIO_UART2_MCR (CVMX_ADD_IO_SEG(0x0001180000000420ull)) -#define CVMX_MIO_UART2_MSR (CVMX_ADD_IO_SEG(0x0001180000000430ull)) -#define CVMX_MIO_UART2_RBR (CVMX_ADD_IO_SEG(0x0001180000000400ull)) -#define CVMX_MIO_UART2_RFL (CVMX_ADD_IO_SEG(0x0001180000000608ull)) -#define CVMX_MIO_UART2_RFW (CVMX_ADD_IO_SEG(0x0001180000000530ull)) -#define CVMX_MIO_UART2_SBCR (CVMX_ADD_IO_SEG(0x0001180000000620ull)) -#define CVMX_MIO_UART2_SCR (CVMX_ADD_IO_SEG(0x0001180000000438ull)) -#define CVMX_MIO_UART2_SFE (CVMX_ADD_IO_SEG(0x0001180000000630ull)) -#define CVMX_MIO_UART2_SRR (CVMX_ADD_IO_SEG(0x0001180000000610ull)) -#define CVMX_MIO_UART2_SRT (CVMX_ADD_IO_SEG(0x0001180000000638ull)) -#define CVMX_MIO_UART2_SRTS (CVMX_ADD_IO_SEG(0x0001180000000618ull)) -#define CVMX_MIO_UART2_STT (CVMX_ADD_IO_SEG(0x0001180000000700ull)) -#define CVMX_MIO_UART2_TFL (CVMX_ADD_IO_SEG(0x0001180000000600ull)) -#define CVMX_MIO_UART2_TFR (CVMX_ADD_IO_SEG(0x0001180000000528ull)) -#define CVMX_MIO_UART2_THR (CVMX_ADD_IO_SEG(0x0001180000000440ull)) -#define CVMX_MIO_UART2_USR (CVMX_ADD_IO_SEG(0x0001180000000538ull)) -#define CVMX_MIO_UARTX_DLH(offset) (CVMX_ADD_IO_SEG(0x0001180000000888ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_DLL(offset) (CVMX_ADD_IO_SEG(0x0001180000000880ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_FAR(offset) (CVMX_ADD_IO_SEG(0x0001180000000920ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_FCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000850ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_HTX(offset) (CVMX_ADD_IO_SEG(0x0001180000000B08ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_IER(offset) (CVMX_ADD_IO_SEG(0x0001180000000808ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_IIR(offset) (CVMX_ADD_IO_SEG(0x0001180000000810ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_LCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000818ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_LSR(offset) (CVMX_ADD_IO_SEG(0x0001180000000828ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_MCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000820ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_MSR(offset) (CVMX_ADD_IO_SEG(0x0001180000000830ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_RBR(offset) (CVMX_ADD_IO_SEG(0x0001180000000800ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_RFL(offset) (CVMX_ADD_IO_SEG(0x0001180000000A08ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_RFW(offset) (CVMX_ADD_IO_SEG(0x0001180000000930ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_SBCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000A20ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_SCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000838ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_SFE(offset) (CVMX_ADD_IO_SEG(0x0001180000000A30ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_SRR(offset) (CVMX_ADD_IO_SEG(0x0001180000000A10ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_SRT(offset) (CVMX_ADD_IO_SEG(0x0001180000000A38ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_SRTS(offset) (CVMX_ADD_IO_SEG(0x0001180000000A18ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_STT(offset) (CVMX_ADD_IO_SEG(0x0001180000000B00ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_TFL(offset) (CVMX_ADD_IO_SEG(0x0001180000000A00ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_TFR(offset) (CVMX_ADD_IO_SEG(0x0001180000000928ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_THR(offset) (CVMX_ADD_IO_SEG(0x0001180000000840ull) + ((offset) & 1) * 1024) -#define CVMX_MIO_UARTX_USR(offset) (CVMX_ADD_IO_SEG(0x0001180000000938ull) + ((offset) & 1) * 1024) +#define CVMX_MIO_BOOT_BIST_STAT \ + CVMX_ADD_IO_SEG(0x00011800000000F8ull) +#define CVMX_MIO_BOOT_COMP \ + CVMX_ADD_IO_SEG(0x00011800000000B8ull) +#define CVMX_MIO_BOOT_DMA_CFGX(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000100ull + (((offset) & 3) * 8)) +#define CVMX_MIO_BOOT_DMA_INTX(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000138ull + (((offset) & 3) * 8)) +#define CVMX_MIO_BOOT_DMA_INT_ENX(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000150ull + (((offset) & 3) * 8)) +#define CVMX_MIO_BOOT_DMA_TIMX(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000120ull + (((offset) & 3) * 8)) +#define CVMX_MIO_BOOT_ERR \ + CVMX_ADD_IO_SEG(0x00011800000000A0ull) +#define CVMX_MIO_BOOT_INT \ + CVMX_ADD_IO_SEG(0x00011800000000A8ull) +#define CVMX_MIO_BOOT_LOC_ADR \ + CVMX_ADD_IO_SEG(0x0001180000000090ull) +#define CVMX_MIO_BOOT_LOC_CFGX(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000080ull + (((offset) & 1) * 8)) +#define CVMX_MIO_BOOT_LOC_DAT \ + CVMX_ADD_IO_SEG(0x0001180000000098ull) +#define CVMX_MIO_BOOT_PIN_DEFS \ + CVMX_ADD_IO_SEG(0x00011800000000C0ull) +#define CVMX_MIO_BOOT_REG_CFGX(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000000ull + (((offset) & 7) * 8)) +#define CVMX_MIO_BOOT_REG_TIMX(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000040ull + (((offset) & 7) * 8)) +#define CVMX_MIO_BOOT_THR \ + CVMX_ADD_IO_SEG(0x00011800000000B0ull) +#define CVMX_MIO_FUS_BNK_DATX(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001520ull + (((offset) & 3) * 8)) +#define CVMX_MIO_FUS_DAT0 \ + CVMX_ADD_IO_SEG(0x0001180000001400ull) +#define CVMX_MIO_FUS_DAT1 \ + CVMX_ADD_IO_SEG(0x0001180000001408ull) +#define CVMX_MIO_FUS_DAT2 \ + CVMX_ADD_IO_SEG(0x0001180000001410ull) +#define CVMX_MIO_FUS_DAT3 \ + CVMX_ADD_IO_SEG(0x0001180000001418ull) +#define CVMX_MIO_FUS_EMA \ + CVMX_ADD_IO_SEG(0x0001180000001550ull) +#define CVMX_MIO_FUS_PDF \ + CVMX_ADD_IO_SEG(0x0001180000001420ull) +#define CVMX_MIO_FUS_PLL \ + CVMX_ADD_IO_SEG(0x0001180000001580ull) +#define CVMX_MIO_FUS_PROG \ + CVMX_ADD_IO_SEG(0x0001180000001510ull) +#define CVMX_MIO_FUS_PROG_TIMES \ + CVMX_ADD_IO_SEG(0x0001180000001518ull) +#define CVMX_MIO_FUS_RCMD \ + CVMX_ADD_IO_SEG(0x0001180000001500ull) +#define CVMX_MIO_FUS_SPR_REPAIR_RES \ + CVMX_ADD_IO_SEG(0x0001180000001548ull) +#define CVMX_MIO_FUS_SPR_REPAIR_SUM \ + CVMX_ADD_IO_SEG(0x0001180000001540ull) +#define CVMX_MIO_FUS_UNLOCK \ + CVMX_ADD_IO_SEG(0x0001180000001578ull) +#define CVMX_MIO_FUS_WADR \ + CVMX_ADD_IO_SEG(0x0001180000001508ull) +#define CVMX_MIO_NDF_DMA_CFG \ + CVMX_ADD_IO_SEG(0x0001180000000168ull) +#define CVMX_MIO_NDF_DMA_INT \ + CVMX_ADD_IO_SEG(0x0001180000000170ull) +#define CVMX_MIO_NDF_DMA_INT_EN \ + CVMX_ADD_IO_SEG(0x0001180000000178ull) +#define CVMX_MIO_PLL_CTL \ + CVMX_ADD_IO_SEG(0x0001180000001448ull) +#define CVMX_MIO_PLL_SETTING \ + CVMX_ADD_IO_SEG(0x0001180000001440ull) +#define CVMX_MIO_TWSX_INT(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001010ull + (((offset) & 1) * 512)) +#define CVMX_MIO_TWSX_SW_TWSI(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001000ull + (((offset) & 1) * 512)) +#define CVMX_MIO_TWSX_SW_TWSI_EXT(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001018ull + (((offset) & 1) * 512)) +#define CVMX_MIO_TWSX_TWSI_SW(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001008ull + (((offset) & 1) * 512)) +#define CVMX_MIO_UART2_DLH \ + CVMX_ADD_IO_SEG(0x0001180000000488ull) +#define CVMX_MIO_UART2_DLL \ + CVMX_ADD_IO_SEG(0x0001180000000480ull) +#define CVMX_MIO_UART2_FAR \ + CVMX_ADD_IO_SEG(0x0001180000000520ull) +#define CVMX_MIO_UART2_FCR \ + CVMX_ADD_IO_SEG(0x0001180000000450ull) +#define CVMX_MIO_UART2_HTX \ + CVMX_ADD_IO_SEG(0x0001180000000708ull) +#define CVMX_MIO_UART2_IER \ + CVMX_ADD_IO_SEG(0x0001180000000408ull) +#define CVMX_MIO_UART2_IIR \ + CVMX_ADD_IO_SEG(0x0001180000000410ull) +#define CVMX_MIO_UART2_LCR \ + CVMX_ADD_IO_SEG(0x0001180000000418ull) +#define CVMX_MIO_UART2_LSR \ + CVMX_ADD_IO_SEG(0x0001180000000428ull) +#define CVMX_MIO_UART2_MCR \ + CVMX_ADD_IO_SEG(0x0001180000000420ull) +#define CVMX_MIO_UART2_MSR \ + CVMX_ADD_IO_SEG(0x0001180000000430ull) +#define CVMX_MIO_UART2_RBR \ + CVMX_ADD_IO_SEG(0x0001180000000400ull) +#define CVMX_MIO_UART2_RFL \ + CVMX_ADD_IO_SEG(0x0001180000000608ull) +#define CVMX_MIO_UART2_RFW \ + CVMX_ADD_IO_SEG(0x0001180000000530ull) +#define CVMX_MIO_UART2_SBCR \ + CVMX_ADD_IO_SEG(0x0001180000000620ull) +#define CVMX_MIO_UART2_SCR \ + CVMX_ADD_IO_SEG(0x0001180000000438ull) +#define CVMX_MIO_UART2_SFE \ + CVMX_ADD_IO_SEG(0x0001180000000630ull) +#define CVMX_MIO_UART2_SRR \ + CVMX_ADD_IO_SEG(0x0001180000000610ull) +#define CVMX_MIO_UART2_SRT \ + CVMX_ADD_IO_SEG(0x0001180000000638ull) +#define CVMX_MIO_UART2_SRTS \ + CVMX_ADD_IO_SEG(0x0001180000000618ull) +#define CVMX_MIO_UART2_STT \ + CVMX_ADD_IO_SEG(0x0001180000000700ull) +#define CVMX_MIO_UART2_TFL \ + CVMX_ADD_IO_SEG(0x0001180000000600ull) +#define CVMX_MIO_UART2_TFR \ + CVMX_ADD_IO_SEG(0x0001180000000528ull) +#define CVMX_MIO_UART2_THR \ + CVMX_ADD_IO_SEG(0x0001180000000440ull) +#define CVMX_MIO_UART2_USR \ + CVMX_ADD_IO_SEG(0x0001180000000538ull) +#define CVMX_MIO_UARTX_DLH(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000888ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_DLL(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000880ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_FAR(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000920ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_FCR(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000850ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_HTX(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000B08ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_IER(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000808ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_IIR(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000810ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_LCR(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000818ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_LSR(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000828ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_MCR(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000820ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_MSR(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000830ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_RBR(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000800ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_RFL(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000A08ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_RFW(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000930ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_SBCR(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000A20ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_SCR(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000838ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_SFE(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000A30ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_SRR(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000A10ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_SRT(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000A38ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_SRTS(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000A18ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_STT(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000B00ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_TFL(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000A00ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_TFR(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000928ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_THR(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000840ull + (((offset) & 1) * 1024)) +#define CVMX_MIO_UARTX_USR(offset) \ + CVMX_ADD_IO_SEG(0x0001180000000938ull + (((offset) & 1) * 1024)) union cvmx_mio_boot_bist_stat { uint64_t u64; struct cvmx_mio_boot_bist_stat_s { - uint64_t reserved_0_63:64; + uint64_t reserved_2_63:62; + uint64_t loc:1; + uint64_t ncbi:1; } s; struct cvmx_mio_boot_bist_stat_cn30xx { uint64_t reserved_4_63:60; @@ -183,33 +257,20 @@ union cvmx_mio_boot_bist_stat { struct cvmx_mio_boot_bist_stat_cn52xxp1 cn56xxp1; struct cvmx_mio_boot_bist_stat_cn38xx cn58xx; struct cvmx_mio_boot_bist_stat_cn38xx cn58xxp1; - struct cvmx_mio_boot_bist_stat_cn63xx { - uint64_t reserved_9_63:55; - uint64_t stat:9; - } cn63xx; - struct cvmx_mio_boot_bist_stat_cn63xx cn63xxp1; }; union cvmx_mio_boot_comp { uint64_t u64; struct cvmx_mio_boot_comp_s { - uint64_t reserved_0_63:64; - } s; - struct cvmx_mio_boot_comp_cn50xx { uint64_t reserved_10_63:54; uint64_t pctl:5; uint64_t nctl:5; - } cn50xx; - struct cvmx_mio_boot_comp_cn50xx cn52xx; - struct cvmx_mio_boot_comp_cn50xx cn52xxp1; - struct cvmx_mio_boot_comp_cn50xx cn56xx; - struct cvmx_mio_boot_comp_cn50xx cn56xxp1; - struct cvmx_mio_boot_comp_cn63xx { - uint64_t reserved_12_63:52; - uint64_t pctl:6; - uint64_t nctl:6; - } cn63xx; - struct cvmx_mio_boot_comp_cn63xx cn63xxp1; + } s; + struct cvmx_mio_boot_comp_s cn50xx; + struct cvmx_mio_boot_comp_s cn52xx; + struct cvmx_mio_boot_comp_s cn52xxp1; + struct cvmx_mio_boot_comp_s cn56xx; + struct cvmx_mio_boot_comp_s cn56xxp1; }; union cvmx_mio_boot_dma_cfgx { @@ -230,8 +291,6 @@ union cvmx_mio_boot_dma_cfgx { struct cvmx_mio_boot_dma_cfgx_s cn52xxp1; struct cvmx_mio_boot_dma_cfgx_s cn56xx; struct cvmx_mio_boot_dma_cfgx_s cn56xxp1; - struct cvmx_mio_boot_dma_cfgx_s cn63xx; - struct cvmx_mio_boot_dma_cfgx_s cn63xxp1; }; union cvmx_mio_boot_dma_intx { @@ -245,8 +304,6 @@ union cvmx_mio_boot_dma_intx { struct cvmx_mio_boot_dma_intx_s cn52xxp1; struct cvmx_mio_boot_dma_intx_s cn56xx; struct cvmx_mio_boot_dma_intx_s cn56xxp1; - struct cvmx_mio_boot_dma_intx_s cn63xx; - struct cvmx_mio_boot_dma_intx_s cn63xxp1; }; union cvmx_mio_boot_dma_int_enx { @@ -260,8 +317,6 @@ union cvmx_mio_boot_dma_int_enx { struct cvmx_mio_boot_dma_int_enx_s cn52xxp1; struct cvmx_mio_boot_dma_int_enx_s cn56xx; struct cvmx_mio_boot_dma_int_enx_s cn56xxp1; - struct cvmx_mio_boot_dma_int_enx_s cn63xx; - struct cvmx_mio_boot_dma_int_enx_s cn63xxp1; }; union cvmx_mio_boot_dma_timx { @@ -287,8 +342,6 @@ union cvmx_mio_boot_dma_timx { struct cvmx_mio_boot_dma_timx_s cn52xxp1; struct cvmx_mio_boot_dma_timx_s cn56xx; struct cvmx_mio_boot_dma_timx_s cn56xxp1; - struct cvmx_mio_boot_dma_timx_s cn63xx; - struct cvmx_mio_boot_dma_timx_s cn63xxp1; }; union cvmx_mio_boot_err { @@ -309,8 +362,6 @@ union cvmx_mio_boot_err { struct cvmx_mio_boot_err_s cn56xxp1; struct cvmx_mio_boot_err_s cn58xx; struct cvmx_mio_boot_err_s cn58xxp1; - struct cvmx_mio_boot_err_s cn63xx; - struct cvmx_mio_boot_err_s cn63xxp1; }; union cvmx_mio_boot_int { @@ -331,8 +382,6 @@ union cvmx_mio_boot_int { struct cvmx_mio_boot_int_s cn56xxp1; struct cvmx_mio_boot_int_s cn58xx; struct cvmx_mio_boot_int_s cn58xxp1; - struct cvmx_mio_boot_int_s cn63xx; - struct cvmx_mio_boot_int_s cn63xxp1; }; union cvmx_mio_boot_loc_adr { @@ -353,8 +402,6 @@ union cvmx_mio_boot_loc_adr { struct cvmx_mio_boot_loc_adr_s cn56xxp1; struct cvmx_mio_boot_loc_adr_s cn58xx; struct cvmx_mio_boot_loc_adr_s cn58xxp1; - struct cvmx_mio_boot_loc_adr_s cn63xx; - struct cvmx_mio_boot_loc_adr_s cn63xxp1; }; union cvmx_mio_boot_loc_cfgx { @@ -377,8 +424,6 @@ union cvmx_mio_boot_loc_cfgx { struct cvmx_mio_boot_loc_cfgx_s cn56xxp1; struct cvmx_mio_boot_loc_cfgx_s cn58xx; struct cvmx_mio_boot_loc_cfgx_s cn58xxp1; - struct cvmx_mio_boot_loc_cfgx_s cn63xx; - struct cvmx_mio_boot_loc_cfgx_s cn63xxp1; }; union cvmx_mio_boot_loc_dat { @@ -397,8 +442,6 @@ union cvmx_mio_boot_loc_dat { struct cvmx_mio_boot_loc_dat_s cn56xxp1; struct cvmx_mio_boot_loc_dat_s cn58xx; struct cvmx_mio_boot_loc_dat_s cn58xxp1; - struct cvmx_mio_boot_loc_dat_s cn63xx; - struct cvmx_mio_boot_loc_dat_s cn63xxp1; }; union cvmx_mio_boot_pin_defs { @@ -435,8 +478,6 @@ union cvmx_mio_boot_pin_defs { uint64_t term:2; uint64_t reserved_0_8:9; } cn56xx; - struct cvmx_mio_boot_pin_defs_cn52xx cn63xx; - struct cvmx_mio_boot_pin_defs_cn52xx cn63xxp1; }; union cvmx_mio_boot_reg_cfgx { @@ -498,8 +539,6 @@ union cvmx_mio_boot_reg_cfgx { struct cvmx_mio_boot_reg_cfgx_s cn56xxp1; struct cvmx_mio_boot_reg_cfgx_cn30xx cn58xx; struct cvmx_mio_boot_reg_cfgx_cn30xx cn58xxp1; - struct cvmx_mio_boot_reg_cfgx_s cn63xx; - struct cvmx_mio_boot_reg_cfgx_s cn63xxp1; }; union cvmx_mio_boot_reg_timx { @@ -544,8 +583,6 @@ union cvmx_mio_boot_reg_timx { struct cvmx_mio_boot_reg_timx_s cn56xxp1; struct cvmx_mio_boot_reg_timx_s cn58xx; struct cvmx_mio_boot_reg_timx_s cn58xxp1; - struct cvmx_mio_boot_reg_timx_s cn63xx; - struct cvmx_mio_boot_reg_timx_s cn63xxp1; }; union cvmx_mio_boot_thr { @@ -574,8 +611,6 @@ union cvmx_mio_boot_thr { struct cvmx_mio_boot_thr_s cn56xxp1; struct cvmx_mio_boot_thr_cn30xx cn58xx; struct cvmx_mio_boot_thr_cn30xx cn58xxp1; - struct cvmx_mio_boot_thr_s cn63xx; - struct cvmx_mio_boot_thr_s cn63xxp1; }; union cvmx_mio_fus_bnk_datx { @@ -590,8 +625,6 @@ union cvmx_mio_fus_bnk_datx { struct cvmx_mio_fus_bnk_datx_s cn56xxp1; struct cvmx_mio_fus_bnk_datx_s cn58xx; struct cvmx_mio_fus_bnk_datx_s cn58xxp1; - struct cvmx_mio_fus_bnk_datx_s cn63xx; - struct cvmx_mio_fus_bnk_datx_s cn63xxp1; }; union cvmx_mio_fus_dat0 { @@ -611,8 +644,6 @@ union cvmx_mio_fus_dat0 { struct cvmx_mio_fus_dat0_s cn56xxp1; struct cvmx_mio_fus_dat0_s cn58xx; struct cvmx_mio_fus_dat0_s cn58xxp1; - struct cvmx_mio_fus_dat0_s cn63xx; - struct cvmx_mio_fus_dat0_s cn63xxp1; }; union cvmx_mio_fus_dat1 { @@ -632,15 +663,12 @@ union cvmx_mio_fus_dat1 { struct cvmx_mio_fus_dat1_s cn56xxp1; struct cvmx_mio_fus_dat1_s cn58xx; struct cvmx_mio_fus_dat1_s cn58xxp1; - struct cvmx_mio_fus_dat1_s cn63xx; - struct cvmx_mio_fus_dat1_s cn63xxp1; }; union cvmx_mio_fus_dat2 { uint64_t u64; struct cvmx_mio_fus_dat2_s { - uint64_t reserved_35_63:29; - uint64_t dorm_crypto:1; + uint64_t reserved_34_63:30; uint64_t fus318:1; uint64_t raid_en:1; uint64_t reserved_30_31:2; @@ -747,38 +775,14 @@ union cvmx_mio_fus_dat2 { uint64_t pp_dis:16; } cn58xx; struct cvmx_mio_fus_dat2_cn58xx cn58xxp1; - struct cvmx_mio_fus_dat2_cn63xx { - uint64_t reserved_35_63:29; - uint64_t dorm_crypto:1; - uint64_t fus318:1; - uint64_t raid_en:1; - uint64_t reserved_29_31:3; - uint64_t nodfa_cp2:1; - uint64_t nomul:1; - uint64_t nocrypto:1; - uint64_t reserved_24_25:2; - uint64_t chip_id:8; - uint64_t reserved_6_15:10; - uint64_t pp_dis:6; - } cn63xx; - struct cvmx_mio_fus_dat2_cn63xx cn63xxp1; }; union cvmx_mio_fus_dat3 { uint64_t u64; struct cvmx_mio_fus_dat3_s { - uint64_t reserved_58_63:6; - uint64_t pll_ctl:10; - uint64_t dfa_info_dte:3; - uint64_t dfa_info_clm:4; - uint64_t reserved_40_40:1; - uint64_t ema:2; - uint64_t efus_lck_rsv:1; - uint64_t efus_lck_man:1; - uint64_t pll_half_dis:1; - uint64_t l2c_crip:3; + uint64_t reserved_32_63:32; uint64_t pll_div4:1; - uint64_t reserved_29_30:2; + uint64_t zip_crip:2; uint64_t bar2_en:1; uint64_t efus_lck:1; uint64_t efus_ign:1; @@ -797,17 +801,7 @@ union cvmx_mio_fus_dat3 { uint64_t nodfa_dte:1; uint64_t icache:24; } cn30xx; - struct cvmx_mio_fus_dat3_cn31xx { - uint64_t reserved_32_63:32; - uint64_t pll_div4:1; - uint64_t zip_crip:2; - uint64_t bar2_en:1; - uint64_t efus_lck:1; - uint64_t efus_ign:1; - uint64_t nozip:1; - uint64_t nodfa_dte:1; - uint64_t icache:24; - } cn31xx; + struct cvmx_mio_fus_dat3_s cn31xx; struct cvmx_mio_fus_dat3_cn38xx { uint64_t reserved_31_63:33; uint64_t zip_crip:2; @@ -834,27 +828,6 @@ union cvmx_mio_fus_dat3 { struct cvmx_mio_fus_dat3_cn38xx cn56xxp1; struct cvmx_mio_fus_dat3_cn38xx cn58xx; struct cvmx_mio_fus_dat3_cn38xx cn58xxp1; - struct cvmx_mio_fus_dat3_cn63xx { - uint64_t reserved_58_63:6; - uint64_t pll_ctl:10; - uint64_t dfa_info_dte:3; - uint64_t dfa_info_clm:4; - uint64_t reserved_40_40:1; - uint64_t ema:2; - uint64_t efus_lck_rsv:1; - uint64_t efus_lck_man:1; - uint64_t pll_half_dis:1; - uint64_t l2c_crip:3; - uint64_t reserved_31_31:1; - uint64_t zip_info:2; - uint64_t bar2_en:1; - uint64_t efus_lck:1; - uint64_t efus_ign:1; - uint64_t nozip:1; - uint64_t nodfa_dte:1; - uint64_t reserved_0_23:24; - } cn63xx; - struct cvmx_mio_fus_dat3_cn63xx cn63xxp1; }; union cvmx_mio_fus_ema { @@ -875,8 +848,6 @@ union cvmx_mio_fus_ema { uint64_t ema:2; } cn58xx; struct cvmx_mio_fus_ema_cn58xx cn58xxp1; - struct cvmx_mio_fus_ema_s cn63xx; - struct cvmx_mio_fus_ema_s cn63xxp1; }; union cvmx_mio_fus_pdf { @@ -890,96 +861,60 @@ union cvmx_mio_fus_pdf { struct cvmx_mio_fus_pdf_s cn56xx; struct cvmx_mio_fus_pdf_s cn56xxp1; struct cvmx_mio_fus_pdf_s cn58xx; - struct cvmx_mio_fus_pdf_s cn63xx; - struct cvmx_mio_fus_pdf_s cn63xxp1; }; union cvmx_mio_fus_pll { uint64_t u64; struct cvmx_mio_fus_pll_s { - uint64_t reserved_8_63:56; - uint64_t c_cout_rst:1; - uint64_t c_cout_sel:2; - uint64_t pnr_cout_rst:1; - uint64_t pnr_cout_sel:2; - uint64_t rfslip:1; - uint64_t fbslip:1; - } s; - struct cvmx_mio_fus_pll_cn50xx { uint64_t reserved_2_63:62; uint64_t rfslip:1; uint64_t fbslip:1; - } cn50xx; - struct cvmx_mio_fus_pll_cn50xx cn52xx; - struct cvmx_mio_fus_pll_cn50xx cn52xxp1; - struct cvmx_mio_fus_pll_cn50xx cn56xx; - struct cvmx_mio_fus_pll_cn50xx cn56xxp1; - struct cvmx_mio_fus_pll_cn50xx cn58xx; - struct cvmx_mio_fus_pll_cn50xx cn58xxp1; - struct cvmx_mio_fus_pll_s cn63xx; - struct cvmx_mio_fus_pll_s cn63xxp1; + } s; + struct cvmx_mio_fus_pll_s cn50xx; + struct cvmx_mio_fus_pll_s cn52xx; + struct cvmx_mio_fus_pll_s cn52xxp1; + struct cvmx_mio_fus_pll_s cn56xx; + struct cvmx_mio_fus_pll_s cn56xxp1; + struct cvmx_mio_fus_pll_s cn58xx; + struct cvmx_mio_fus_pll_s cn58xxp1; }; union cvmx_mio_fus_prog { uint64_t u64; struct cvmx_mio_fus_prog_s { - uint64_t reserved_2_63:62; - uint64_t soft:1; - uint64_t prog:1; - } s; - struct cvmx_mio_fus_prog_cn30xx { uint64_t reserved_1_63:63; uint64_t prog:1; - } cn30xx; - struct cvmx_mio_fus_prog_cn30xx cn31xx; - struct cvmx_mio_fus_prog_cn30xx cn38xx; - struct cvmx_mio_fus_prog_cn30xx cn38xxp2; - struct cvmx_mio_fus_prog_cn30xx cn50xx; - struct cvmx_mio_fus_prog_cn30xx cn52xx; - struct cvmx_mio_fus_prog_cn30xx cn52xxp1; - struct cvmx_mio_fus_prog_cn30xx cn56xx; - struct cvmx_mio_fus_prog_cn30xx cn56xxp1; - struct cvmx_mio_fus_prog_cn30xx cn58xx; - struct cvmx_mio_fus_prog_cn30xx cn58xxp1; - struct cvmx_mio_fus_prog_s cn63xx; - struct cvmx_mio_fus_prog_s cn63xxp1; + } s; + struct cvmx_mio_fus_prog_s cn30xx; + struct cvmx_mio_fus_prog_s cn31xx; + struct cvmx_mio_fus_prog_s cn38xx; + struct cvmx_mio_fus_prog_s cn38xxp2; + struct cvmx_mio_fus_prog_s cn50xx; + struct cvmx_mio_fus_prog_s cn52xx; + struct cvmx_mio_fus_prog_s cn52xxp1; + struct cvmx_mio_fus_prog_s cn56xx; + struct cvmx_mio_fus_prog_s cn56xxp1; + struct cvmx_mio_fus_prog_s cn58xx; + struct cvmx_mio_fus_prog_s cn58xxp1; }; union cvmx_mio_fus_prog_times { uint64_t u64; struct cvmx_mio_fus_prog_times_s { - uint64_t reserved_35_63:29; - uint64_t vgate_pin:1; - uint64_t fsrc_pin:1; - uint64_t prog_pin:1; - uint64_t reserved_6_31:26; - uint64_t setup:6; - } s; - struct cvmx_mio_fus_prog_times_cn50xx { uint64_t reserved_33_63:31; uint64_t prog_pin:1; uint64_t out:8; uint64_t sclk_lo:4; uint64_t sclk_hi:12; uint64_t setup:8; - } cn50xx; - struct cvmx_mio_fus_prog_times_cn50xx cn52xx; - struct cvmx_mio_fus_prog_times_cn50xx cn52xxp1; - struct cvmx_mio_fus_prog_times_cn50xx cn56xx; - struct cvmx_mio_fus_prog_times_cn50xx cn56xxp1; - struct cvmx_mio_fus_prog_times_cn50xx cn58xx; - struct cvmx_mio_fus_prog_times_cn50xx cn58xxp1; - struct cvmx_mio_fus_prog_times_cn63xx { - uint64_t reserved_35_63:29; - uint64_t vgate_pin:1; - uint64_t fsrc_pin:1; - uint64_t prog_pin:1; - uint64_t out:7; - uint64_t sclk_lo:4; - uint64_t sclk_hi:15; - uint64_t setup:6; - } cn63xx; - struct cvmx_mio_fus_prog_times_cn63xx cn63xxp1; + } s; + struct cvmx_mio_fus_prog_times_s cn50xx; + struct cvmx_mio_fus_prog_times_s cn52xx; + struct cvmx_mio_fus_prog_times_s cn52xxp1; + struct cvmx_mio_fus_prog_times_s cn56xx; + struct cvmx_mio_fus_prog_times_s cn56xxp1; + struct cvmx_mio_fus_prog_times_s cn58xx; + struct cvmx_mio_fus_prog_times_s cn58xxp1; }; union cvmx_mio_fus_rcmd { @@ -1013,57 +948,6 @@ union cvmx_mio_fus_rcmd { struct cvmx_mio_fus_rcmd_s cn56xxp1; struct cvmx_mio_fus_rcmd_cn30xx cn58xx; struct cvmx_mio_fus_rcmd_cn30xx cn58xxp1; - struct cvmx_mio_fus_rcmd_s cn63xx; - struct cvmx_mio_fus_rcmd_s cn63xxp1; -}; - -union cvmx_mio_fus_read_times { - uint64_t u64; - struct cvmx_mio_fus_read_times_s { - uint64_t reserved_26_63:38; - uint64_t sch:4; - uint64_t fsh:4; - uint64_t prh:4; - uint64_t sdh:4; - uint64_t setup:10; - } s; - struct cvmx_mio_fus_read_times_s cn63xx; - struct cvmx_mio_fus_read_times_s cn63xxp1; -}; - -union cvmx_mio_fus_repair_res0 { - uint64_t u64; - struct cvmx_mio_fus_repair_res0_s { - uint64_t reserved_55_63:9; - uint64_t too_many:1; - uint64_t repair2:18; - uint64_t repair1:18; - uint64_t repair0:18; - } s; - struct cvmx_mio_fus_repair_res0_s cn63xx; - struct cvmx_mio_fus_repair_res0_s cn63xxp1; -}; - -union cvmx_mio_fus_repair_res1 { - uint64_t u64; - struct cvmx_mio_fus_repair_res1_s { - uint64_t reserved_54_63:10; - uint64_t repair5:18; - uint64_t repair4:18; - uint64_t repair3:18; - } s; - struct cvmx_mio_fus_repair_res1_s cn63xx; - struct cvmx_mio_fus_repair_res1_s cn63xxp1; -}; - -union cvmx_mio_fus_repair_res2 { - uint64_t u64; - struct cvmx_mio_fus_repair_res2_s { - uint64_t reserved_18_63:46; - uint64_t repair6:18; - } s; - struct cvmx_mio_fus_repair_res2_s cn63xx; - struct cvmx_mio_fus_repair_res2_s cn63xxp1; }; union cvmx_mio_fus_spr_repair_res { @@ -1084,8 +968,6 @@ union cvmx_mio_fus_spr_repair_res { struct cvmx_mio_fus_spr_repair_res_s cn56xxp1; struct cvmx_mio_fus_spr_repair_res_s cn58xx; struct cvmx_mio_fus_spr_repair_res_s cn58xxp1; - struct cvmx_mio_fus_spr_repair_res_s cn63xx; - struct cvmx_mio_fus_spr_repair_res_s cn63xxp1; }; union cvmx_mio_fus_spr_repair_sum { @@ -1104,8 +986,6 @@ union cvmx_mio_fus_spr_repair_sum { struct cvmx_mio_fus_spr_repair_sum_s cn56xxp1; struct cvmx_mio_fus_spr_repair_sum_s cn58xx; struct cvmx_mio_fus_spr_repair_sum_s cn58xxp1; - struct cvmx_mio_fus_spr_repair_sum_s cn63xx; - struct cvmx_mio_fus_spr_repair_sum_s cn63xxp1; }; union cvmx_mio_fus_unlock { @@ -1141,22 +1021,6 @@ union cvmx_mio_fus_wadr { struct cvmx_mio_fus_wadr_cn52xx cn56xxp1; struct cvmx_mio_fus_wadr_cn50xx cn58xx; struct cvmx_mio_fus_wadr_cn50xx cn58xxp1; - struct cvmx_mio_fus_wadr_cn63xx { - uint64_t reserved_4_63:60; - uint64_t addr:4; - } cn63xx; - struct cvmx_mio_fus_wadr_cn63xx cn63xxp1; -}; - -union cvmx_mio_gpio_comp { - uint64_t u64; - struct cvmx_mio_gpio_comp_s { - uint64_t reserved_12_63:52; - uint64_t pctl:6; - uint64_t nctl:6; - } s; - struct cvmx_mio_gpio_comp_s cn63xx; - struct cvmx_mio_gpio_comp_s cn63xxp1; }; union cvmx_mio_ndf_dma_cfg { @@ -1174,8 +1038,6 @@ union cvmx_mio_ndf_dma_cfg { uint64_t adr:36; } s; struct cvmx_mio_ndf_dma_cfg_s cn52xx; - struct cvmx_mio_ndf_dma_cfg_s cn63xx; - struct cvmx_mio_ndf_dma_cfg_s cn63xxp1; }; union cvmx_mio_ndf_dma_int { @@ -1185,8 +1047,6 @@ union cvmx_mio_ndf_dma_int { uint64_t done:1; } s; struct cvmx_mio_ndf_dma_int_s cn52xx; - struct cvmx_mio_ndf_dma_int_s cn63xx; - struct cvmx_mio_ndf_dma_int_s cn63xxp1; }; union cvmx_mio_ndf_dma_int_en { @@ -1196,8 +1056,6 @@ union cvmx_mio_ndf_dma_int_en { uint64_t done:1; } s; struct cvmx_mio_ndf_dma_int_en_s cn52xx; - struct cvmx_mio_ndf_dma_int_en_s cn63xx; - struct cvmx_mio_ndf_dma_int_en_s cn63xxp1; }; union cvmx_mio_pll_ctl { @@ -1220,173 +1078,6 @@ union cvmx_mio_pll_setting { struct cvmx_mio_pll_setting_s cn31xx; }; -union cvmx_mio_ptp_clock_cfg { - uint64_t u64; - struct cvmx_mio_ptp_clock_cfg_s { - uint64_t reserved_24_63:40; - uint64_t evcnt_in:6; - uint64_t evcnt_edge:1; - uint64_t evcnt_en:1; - uint64_t tstmp_in:6; - uint64_t tstmp_edge:1; - uint64_t tstmp_en:1; - uint64_t ext_clk_in:6; - uint64_t ext_clk_en:1; - uint64_t ptp_en:1; - } s; - struct cvmx_mio_ptp_clock_cfg_s cn63xx; - struct cvmx_mio_ptp_clock_cfg_s cn63xxp1; -}; - -union cvmx_mio_ptp_clock_comp { - uint64_t u64; - struct cvmx_mio_ptp_clock_comp_s { - uint64_t nanosec:32; - uint64_t frnanosec:32; - } s; - struct cvmx_mio_ptp_clock_comp_s cn63xx; - struct cvmx_mio_ptp_clock_comp_s cn63xxp1; -}; - -union cvmx_mio_ptp_clock_hi { - uint64_t u64; - struct cvmx_mio_ptp_clock_hi_s { - uint64_t nanosec:64; - } s; - struct cvmx_mio_ptp_clock_hi_s cn63xx; - struct cvmx_mio_ptp_clock_hi_s cn63xxp1; -}; - -union cvmx_mio_ptp_clock_lo { - uint64_t u64; - struct cvmx_mio_ptp_clock_lo_s { - uint64_t reserved_32_63:32; - uint64_t frnanosec:32; - } s; - struct cvmx_mio_ptp_clock_lo_s cn63xx; - struct cvmx_mio_ptp_clock_lo_s cn63xxp1; -}; - -union cvmx_mio_ptp_evt_cnt { - uint64_t u64; - struct cvmx_mio_ptp_evt_cnt_s { - uint64_t cntr:64; - } s; - struct cvmx_mio_ptp_evt_cnt_s cn63xx; - struct cvmx_mio_ptp_evt_cnt_s cn63xxp1; -}; - -union cvmx_mio_ptp_timestamp { - uint64_t u64; - struct cvmx_mio_ptp_timestamp_s { - uint64_t nanosec:64; - } s; - struct cvmx_mio_ptp_timestamp_s cn63xx; - struct cvmx_mio_ptp_timestamp_s cn63xxp1; -}; - -union cvmx_mio_rst_boot { - uint64_t u64; - struct cvmx_mio_rst_boot_s { - uint64_t reserved_36_63:28; - uint64_t c_mul:6; - uint64_t pnr_mul:6; - uint64_t qlm2_spd:4; - uint64_t qlm1_spd:4; - uint64_t qlm0_spd:4; - uint64_t lboot:10; - uint64_t rboot:1; - uint64_t rboot_pin:1; - } s; - struct cvmx_mio_rst_boot_s cn63xx; - struct cvmx_mio_rst_boot_s cn63xxp1; -}; - -union cvmx_mio_rst_cfg { - uint64_t u64; - struct cvmx_mio_rst_cfg_s { - uint64_t bist_delay:58; - uint64_t reserved_3_5:3; - uint64_t cntl_clr_bist:1; - uint64_t warm_clr_bist:1; - uint64_t soft_clr_bist:1; - } s; - struct cvmx_mio_rst_cfg_s cn63xx; - struct cvmx_mio_rst_cfg_cn63xxp1 { - uint64_t bist_delay:58; - uint64_t reserved_2_5:4; - uint64_t warm_clr_bist:1; - uint64_t soft_clr_bist:1; - } cn63xxp1; -}; - -union cvmx_mio_rst_ctlx { - uint64_t u64; - struct cvmx_mio_rst_ctlx_s { - uint64_t reserved_10_63:54; - uint64_t prst_link:1; - uint64_t rst_done:1; - uint64_t rst_link:1; - uint64_t host_mode:1; - uint64_t prtmode:2; - uint64_t rst_drv:1; - uint64_t rst_rcv:1; - uint64_t rst_chip:1; - uint64_t rst_val:1; - } s; - struct cvmx_mio_rst_ctlx_s cn63xx; - struct cvmx_mio_rst_ctlx_cn63xxp1 { - uint64_t reserved_9_63:55; - uint64_t rst_done:1; - uint64_t rst_link:1; - uint64_t host_mode:1; - uint64_t prtmode:2; - uint64_t rst_drv:1; - uint64_t rst_rcv:1; - uint64_t rst_chip:1; - uint64_t rst_val:1; - } cn63xxp1; -}; - -union cvmx_mio_rst_delay { - uint64_t u64; - struct cvmx_mio_rst_delay_s { - uint64_t reserved_32_63:32; - uint64_t soft_rst_dly:16; - uint64_t warm_rst_dly:16; - } s; - struct cvmx_mio_rst_delay_s cn63xx; - struct cvmx_mio_rst_delay_s cn63xxp1; -}; - -union cvmx_mio_rst_int { - uint64_t u64; - struct cvmx_mio_rst_int_s { - uint64_t reserved_10_63:54; - uint64_t perst1:1; - uint64_t perst0:1; - uint64_t reserved_2_7:6; - uint64_t rst_link1:1; - uint64_t rst_link0:1; - } s; - struct cvmx_mio_rst_int_s cn63xx; - struct cvmx_mio_rst_int_s cn63xxp1; -}; - -union cvmx_mio_rst_int_en { - uint64_t u64; - struct cvmx_mio_rst_int_en_s { - uint64_t reserved_10_63:54; - uint64_t perst1:1; - uint64_t perst0:1; - uint64_t reserved_2_7:6; - uint64_t rst_link1:1; - uint64_t rst_link0:1; - } s; - struct cvmx_mio_rst_int_en_s cn63xx; - struct cvmx_mio_rst_int_en_s cn63xxp1; -}; - union cvmx_mio_twsx_int { uint64_t u64; struct cvmx_mio_twsx_int_s { @@ -1424,8 +1115,6 @@ union cvmx_mio_twsx_int { struct cvmx_mio_twsx_int_s cn56xxp1; struct cvmx_mio_twsx_int_s cn58xx; struct cvmx_mio_twsx_int_s cn58xxp1; - struct cvmx_mio_twsx_int_s cn63xx; - struct cvmx_mio_twsx_int_s cn63xxp1; }; union cvmx_mio_twsx_sw_twsi { @@ -1455,8 +1144,6 @@ union cvmx_mio_twsx_sw_twsi { struct cvmx_mio_twsx_sw_twsi_s cn56xxp1; struct cvmx_mio_twsx_sw_twsi_s cn58xx; struct cvmx_mio_twsx_sw_twsi_s cn58xxp1; - struct cvmx_mio_twsx_sw_twsi_s cn63xx; - struct cvmx_mio_twsx_sw_twsi_s cn63xxp1; }; union cvmx_mio_twsx_sw_twsi_ext { @@ -1477,8 +1164,6 @@ union cvmx_mio_twsx_sw_twsi_ext { struct cvmx_mio_twsx_sw_twsi_ext_s cn56xxp1; struct cvmx_mio_twsx_sw_twsi_ext_s cn58xx; struct cvmx_mio_twsx_sw_twsi_ext_s cn58xxp1; - struct cvmx_mio_twsx_sw_twsi_ext_s cn63xx; - struct cvmx_mio_twsx_sw_twsi_ext_s cn63xxp1; }; union cvmx_mio_twsx_twsi_sw { @@ -1499,8 +1184,6 @@ union cvmx_mio_twsx_twsi_sw { struct cvmx_mio_twsx_twsi_sw_s cn56xxp1; struct cvmx_mio_twsx_twsi_sw_s cn58xx; struct cvmx_mio_twsx_twsi_sw_s cn58xxp1; - struct cvmx_mio_twsx_twsi_sw_s cn63xx; - struct cvmx_mio_twsx_twsi_sw_s cn63xxp1; }; union cvmx_mio_uartx_dlh { @@ -1520,8 +1203,6 @@ union cvmx_mio_uartx_dlh { struct cvmx_mio_uartx_dlh_s cn56xxp1; struct cvmx_mio_uartx_dlh_s cn58xx; struct cvmx_mio_uartx_dlh_s cn58xxp1; - struct cvmx_mio_uartx_dlh_s cn63xx; - struct cvmx_mio_uartx_dlh_s cn63xxp1; }; union cvmx_mio_uartx_dll { @@ -1541,8 +1222,6 @@ union cvmx_mio_uartx_dll { struct cvmx_mio_uartx_dll_s cn56xxp1; struct cvmx_mio_uartx_dll_s cn58xx; struct cvmx_mio_uartx_dll_s cn58xxp1; - struct cvmx_mio_uartx_dll_s cn63xx; - struct cvmx_mio_uartx_dll_s cn63xxp1; }; union cvmx_mio_uartx_far { @@ -1562,8 +1241,6 @@ union cvmx_mio_uartx_far { struct cvmx_mio_uartx_far_s cn56xxp1; struct cvmx_mio_uartx_far_s cn58xx; struct cvmx_mio_uartx_far_s cn58xxp1; - struct cvmx_mio_uartx_far_s cn63xx; - struct cvmx_mio_uartx_far_s cn63xxp1; }; union cvmx_mio_uartx_fcr { @@ -1588,8 +1265,6 @@ union cvmx_mio_uartx_fcr { struct cvmx_mio_uartx_fcr_s cn56xxp1; struct cvmx_mio_uartx_fcr_s cn58xx; struct cvmx_mio_uartx_fcr_s cn58xxp1; - struct cvmx_mio_uartx_fcr_s cn63xx; - struct cvmx_mio_uartx_fcr_s cn63xxp1; }; union cvmx_mio_uartx_htx { @@ -1609,8 +1284,6 @@ union cvmx_mio_uartx_htx { struct cvmx_mio_uartx_htx_s cn56xxp1; struct cvmx_mio_uartx_htx_s cn58xx; struct cvmx_mio_uartx_htx_s cn58xxp1; - struct cvmx_mio_uartx_htx_s cn63xx; - struct cvmx_mio_uartx_htx_s cn63xxp1; }; union cvmx_mio_uartx_ier { @@ -1635,8 +1308,6 @@ union cvmx_mio_uartx_ier { struct cvmx_mio_uartx_ier_s cn56xxp1; struct cvmx_mio_uartx_ier_s cn58xx; struct cvmx_mio_uartx_ier_s cn58xxp1; - struct cvmx_mio_uartx_ier_s cn63xx; - struct cvmx_mio_uartx_ier_s cn63xxp1; }; union cvmx_mio_uartx_iir { @@ -1658,8 +1329,6 @@ union cvmx_mio_uartx_iir { struct cvmx_mio_uartx_iir_s cn56xxp1; struct cvmx_mio_uartx_iir_s cn58xx; struct cvmx_mio_uartx_iir_s cn58xxp1; - struct cvmx_mio_uartx_iir_s cn63xx; - struct cvmx_mio_uartx_iir_s cn63xxp1; }; union cvmx_mio_uartx_lcr { @@ -1685,8 +1354,6 @@ union cvmx_mio_uartx_lcr { struct cvmx_mio_uartx_lcr_s cn56xxp1; struct cvmx_mio_uartx_lcr_s cn58xx; struct cvmx_mio_uartx_lcr_s cn58xxp1; - struct cvmx_mio_uartx_lcr_s cn63xx; - struct cvmx_mio_uartx_lcr_s cn63xxp1; }; union cvmx_mio_uartx_lsr { @@ -1713,8 +1380,6 @@ union cvmx_mio_uartx_lsr { struct cvmx_mio_uartx_lsr_s cn56xxp1; struct cvmx_mio_uartx_lsr_s cn58xx; struct cvmx_mio_uartx_lsr_s cn58xxp1; - struct cvmx_mio_uartx_lsr_s cn63xx; - struct cvmx_mio_uartx_lsr_s cn63xxp1; }; union cvmx_mio_uartx_mcr { @@ -1739,8 +1404,6 @@ union cvmx_mio_uartx_mcr { struct cvmx_mio_uartx_mcr_s cn56xxp1; struct cvmx_mio_uartx_mcr_s cn58xx; struct cvmx_mio_uartx_mcr_s cn58xxp1; - struct cvmx_mio_uartx_mcr_s cn63xx; - struct cvmx_mio_uartx_mcr_s cn63xxp1; }; union cvmx_mio_uartx_msr { @@ -1767,8 +1430,6 @@ union cvmx_mio_uartx_msr { struct cvmx_mio_uartx_msr_s cn56xxp1; struct cvmx_mio_uartx_msr_s cn58xx; struct cvmx_mio_uartx_msr_s cn58xxp1; - struct cvmx_mio_uartx_msr_s cn63xx; - struct cvmx_mio_uartx_msr_s cn63xxp1; }; union cvmx_mio_uartx_rbr { @@ -1788,8 +1449,6 @@ union cvmx_mio_uartx_rbr { struct cvmx_mio_uartx_rbr_s cn56xxp1; struct cvmx_mio_uartx_rbr_s cn58xx; struct cvmx_mio_uartx_rbr_s cn58xxp1; - struct cvmx_mio_uartx_rbr_s cn63xx; - struct cvmx_mio_uartx_rbr_s cn63xxp1; }; union cvmx_mio_uartx_rfl { @@ -1809,8 +1468,6 @@ union cvmx_mio_uartx_rfl { struct cvmx_mio_uartx_rfl_s cn56xxp1; struct cvmx_mio_uartx_rfl_s cn58xx; struct cvmx_mio_uartx_rfl_s cn58xxp1; - struct cvmx_mio_uartx_rfl_s cn63xx; - struct cvmx_mio_uartx_rfl_s cn63xxp1; }; union cvmx_mio_uartx_rfw { @@ -1832,8 +1489,6 @@ union cvmx_mio_uartx_rfw { struct cvmx_mio_uartx_rfw_s cn56xxp1; struct cvmx_mio_uartx_rfw_s cn58xx; struct cvmx_mio_uartx_rfw_s cn58xxp1; - struct cvmx_mio_uartx_rfw_s cn63xx; - struct cvmx_mio_uartx_rfw_s cn63xxp1; }; union cvmx_mio_uartx_sbcr { @@ -1853,8 +1508,6 @@ union cvmx_mio_uartx_sbcr { struct cvmx_mio_uartx_sbcr_s cn56xxp1; struct cvmx_mio_uartx_sbcr_s cn58xx; struct cvmx_mio_uartx_sbcr_s cn58xxp1; - struct cvmx_mio_uartx_sbcr_s cn63xx; - struct cvmx_mio_uartx_sbcr_s cn63xxp1; }; union cvmx_mio_uartx_scr { @@ -1874,8 +1527,6 @@ union cvmx_mio_uartx_scr { struct cvmx_mio_uartx_scr_s cn56xxp1; struct cvmx_mio_uartx_scr_s cn58xx; struct cvmx_mio_uartx_scr_s cn58xxp1; - struct cvmx_mio_uartx_scr_s cn63xx; - struct cvmx_mio_uartx_scr_s cn63xxp1; }; union cvmx_mio_uartx_sfe { @@ -1895,8 +1546,6 @@ union cvmx_mio_uartx_sfe { struct cvmx_mio_uartx_sfe_s cn56xxp1; struct cvmx_mio_uartx_sfe_s cn58xx; struct cvmx_mio_uartx_sfe_s cn58xxp1; - struct cvmx_mio_uartx_sfe_s cn63xx; - struct cvmx_mio_uartx_sfe_s cn63xxp1; }; union cvmx_mio_uartx_srr { @@ -1918,8 +1567,6 @@ union cvmx_mio_uartx_srr { struct cvmx_mio_uartx_srr_s cn56xxp1; struct cvmx_mio_uartx_srr_s cn58xx; struct cvmx_mio_uartx_srr_s cn58xxp1; - struct cvmx_mio_uartx_srr_s cn63xx; - struct cvmx_mio_uartx_srr_s cn63xxp1; }; union cvmx_mio_uartx_srt { @@ -1939,8 +1586,6 @@ union cvmx_mio_uartx_srt { struct cvmx_mio_uartx_srt_s cn56xxp1; struct cvmx_mio_uartx_srt_s cn58xx; struct cvmx_mio_uartx_srt_s cn58xxp1; - struct cvmx_mio_uartx_srt_s cn63xx; - struct cvmx_mio_uartx_srt_s cn63xxp1; }; union cvmx_mio_uartx_srts { @@ -1960,8 +1605,6 @@ union cvmx_mio_uartx_srts { struct cvmx_mio_uartx_srts_s cn56xxp1; struct cvmx_mio_uartx_srts_s cn58xx; struct cvmx_mio_uartx_srts_s cn58xxp1; - struct cvmx_mio_uartx_srts_s cn63xx; - struct cvmx_mio_uartx_srts_s cn63xxp1; }; union cvmx_mio_uartx_stt { @@ -1981,8 +1624,6 @@ union cvmx_mio_uartx_stt { struct cvmx_mio_uartx_stt_s cn56xxp1; struct cvmx_mio_uartx_stt_s cn58xx; struct cvmx_mio_uartx_stt_s cn58xxp1; - struct cvmx_mio_uartx_stt_s cn63xx; - struct cvmx_mio_uartx_stt_s cn63xxp1; }; union cvmx_mio_uartx_tfl { @@ -2002,8 +1643,6 @@ union cvmx_mio_uartx_tfl { struct cvmx_mio_uartx_tfl_s cn56xxp1; struct cvmx_mio_uartx_tfl_s cn58xx; struct cvmx_mio_uartx_tfl_s cn58xxp1; - struct cvmx_mio_uartx_tfl_s cn63xx; - struct cvmx_mio_uartx_tfl_s cn63xxp1; }; union cvmx_mio_uartx_tfr { @@ -2023,8 +1662,6 @@ union cvmx_mio_uartx_tfr { struct cvmx_mio_uartx_tfr_s cn56xxp1; struct cvmx_mio_uartx_tfr_s cn58xx; struct cvmx_mio_uartx_tfr_s cn58xxp1; - struct cvmx_mio_uartx_tfr_s cn63xx; - struct cvmx_mio_uartx_tfr_s cn63xxp1; }; union cvmx_mio_uartx_thr { @@ -2044,8 +1681,6 @@ union cvmx_mio_uartx_thr { struct cvmx_mio_uartx_thr_s cn56xxp1; struct cvmx_mio_uartx_thr_s cn58xx; struct cvmx_mio_uartx_thr_s cn58xxp1; - struct cvmx_mio_uartx_thr_s cn63xx; - struct cvmx_mio_uartx_thr_s cn63xxp1; }; union cvmx_mio_uartx_usr { @@ -2069,8 +1704,6 @@ union cvmx_mio_uartx_usr { struct cvmx_mio_uartx_usr_s cn56xxp1; struct cvmx_mio_uartx_usr_s cn58xx; struct cvmx_mio_uartx_usr_s cn58xxp1; - struct cvmx_mio_uartx_usr_s cn63xx; - struct cvmx_mio_uartx_usr_s cn63xxp1; }; union cvmx_mio_uart2_dlh { diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-mixx-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-mixx-defs.h index 7057c447e69e..dab6dca492f9 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-mixx-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-mixx-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,61 +28,51 @@ #ifndef __CVMX_MIXX_DEFS_H__ #define __CVMX_MIXX_DEFS_H__ -#define CVMX_MIXX_BIST(offset) (CVMX_ADD_IO_SEG(0x0001070000100078ull) + ((offset) & 1) * 2048) -#define CVMX_MIXX_CTL(offset) (CVMX_ADD_IO_SEG(0x0001070000100020ull) + ((offset) & 1) * 2048) -#define CVMX_MIXX_INTENA(offset) (CVMX_ADD_IO_SEG(0x0001070000100050ull) + ((offset) & 1) * 2048) -#define CVMX_MIXX_IRCNT(offset) (CVMX_ADD_IO_SEG(0x0001070000100030ull) + ((offset) & 1) * 2048) -#define CVMX_MIXX_IRHWM(offset) (CVMX_ADD_IO_SEG(0x0001070000100028ull) + ((offset) & 1) * 2048) -#define CVMX_MIXX_IRING1(offset) (CVMX_ADD_IO_SEG(0x0001070000100010ull) + ((offset) & 1) * 2048) -#define CVMX_MIXX_IRING2(offset) (CVMX_ADD_IO_SEG(0x0001070000100018ull) + ((offset) & 1) * 2048) -#define CVMX_MIXX_ISR(offset) (CVMX_ADD_IO_SEG(0x0001070000100048ull) + ((offset) & 1) * 2048) -#define CVMX_MIXX_ORCNT(offset) (CVMX_ADD_IO_SEG(0x0001070000100040ull) + ((offset) & 1) * 2048) -#define CVMX_MIXX_ORHWM(offset) (CVMX_ADD_IO_SEG(0x0001070000100038ull) + ((offset) & 1) * 2048) -#define CVMX_MIXX_ORING1(offset) (CVMX_ADD_IO_SEG(0x0001070000100000ull) + ((offset) & 1) * 2048) -#define CVMX_MIXX_ORING2(offset) (CVMX_ADD_IO_SEG(0x0001070000100008ull) + ((offset) & 1) * 2048) -#define CVMX_MIXX_REMCNT(offset) (CVMX_ADD_IO_SEG(0x0001070000100058ull) + ((offset) & 1) * 2048) -#define CVMX_MIXX_TSCTL(offset) (CVMX_ADD_IO_SEG(0x0001070000100068ull) + ((offset) & 1) * 2048) -#define CVMX_MIXX_TSTAMP(offset) (CVMX_ADD_IO_SEG(0x0001070000100060ull) + ((offset) & 1) * 2048) +#define CVMX_MIXX_BIST(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100078ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_CTL(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100020ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_INTENA(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100050ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_IRCNT(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100030ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_IRHWM(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100028ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_IRING1(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100010ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_IRING2(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100018ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_ISR(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100048ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_ORCNT(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100040ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_ORHWM(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100038ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_ORING1(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100000ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_ORING2(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100008ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_REMCNT(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100058ull + (((offset) & 1) * 2048)) union cvmx_mixx_bist { uint64_t u64; struct cvmx_mixx_bist_s { - uint64_t reserved_6_63:58; - uint64_t opfdat:1; - uint64_t mrgdat:1; - uint64_t mrqdat:1; - uint64_t ipfdat:1; - uint64_t irfdat:1; - uint64_t orfdat:1; - } s; - struct cvmx_mixx_bist_cn52xx { uint64_t reserved_4_63:60; uint64_t mrqdat:1; uint64_t ipfdat:1; uint64_t irfdat:1; uint64_t orfdat:1; - } cn52xx; - struct cvmx_mixx_bist_cn52xx cn52xxp1; - struct cvmx_mixx_bist_cn52xx cn56xx; - struct cvmx_mixx_bist_cn52xx cn56xxp1; - struct cvmx_mixx_bist_s cn63xx; - struct cvmx_mixx_bist_s cn63xxp1; + } s; + struct cvmx_mixx_bist_s cn52xx; + struct cvmx_mixx_bist_s cn52xxp1; + struct cvmx_mixx_bist_s cn56xx; + struct cvmx_mixx_bist_s cn56xxp1; }; union cvmx_mixx_ctl { uint64_t u64; struct cvmx_mixx_ctl_s { - uint64_t reserved_12_63:52; - uint64_t ts_thresh:4; - uint64_t crc_strip:1; - uint64_t busy:1; - uint64_t en:1; - uint64_t reset:1; - uint64_t lendian:1; - uint64_t nbtarb:1; - uint64_t mrq_hwm:2; - } s; - struct cvmx_mixx_ctl_cn52xx { uint64_t reserved_8_63:56; uint64_t crc_strip:1; uint64_t busy:1; @@ -91,28 +81,16 @@ union cvmx_mixx_ctl { uint64_t lendian:1; uint64_t nbtarb:1; uint64_t mrq_hwm:2; - } cn52xx; - struct cvmx_mixx_ctl_cn52xx cn52xxp1; - struct cvmx_mixx_ctl_cn52xx cn56xx; - struct cvmx_mixx_ctl_cn52xx cn56xxp1; - struct cvmx_mixx_ctl_s cn63xx; - struct cvmx_mixx_ctl_s cn63xxp1; + } s; + struct cvmx_mixx_ctl_s cn52xx; + struct cvmx_mixx_ctl_s cn52xxp1; + struct cvmx_mixx_ctl_s cn56xx; + struct cvmx_mixx_ctl_s cn56xxp1; }; union cvmx_mixx_intena { uint64_t u64; struct cvmx_mixx_intena_s { - uint64_t reserved_8_63:56; - uint64_t tsena:1; - uint64_t orunena:1; - uint64_t irunena:1; - uint64_t data_drpena:1; - uint64_t ithena:1; - uint64_t othena:1; - uint64_t ivfena:1; - uint64_t ovfena:1; - } s; - struct cvmx_mixx_intena_cn52xx { uint64_t reserved_7_63:57; uint64_t orunena:1; uint64_t irunena:1; @@ -121,12 +99,11 @@ union cvmx_mixx_intena { uint64_t othena:1; uint64_t ivfena:1; uint64_t ovfena:1; - } cn52xx; - struct cvmx_mixx_intena_cn52xx cn52xxp1; - struct cvmx_mixx_intena_cn52xx cn56xx; - struct cvmx_mixx_intena_cn52xx cn56xxp1; - struct cvmx_mixx_intena_s cn63xx; - struct cvmx_mixx_intena_s cn63xxp1; + } s; + struct cvmx_mixx_intena_s cn52xx; + struct cvmx_mixx_intena_s cn52xxp1; + struct cvmx_mixx_intena_s cn56xx; + struct cvmx_mixx_intena_s cn56xxp1; }; union cvmx_mixx_ircnt { @@ -139,8 +116,6 @@ union cvmx_mixx_ircnt { struct cvmx_mixx_ircnt_s cn52xxp1; struct cvmx_mixx_ircnt_s cn56xx; struct cvmx_mixx_ircnt_s cn56xxp1; - struct cvmx_mixx_ircnt_s cn63xx; - struct cvmx_mixx_ircnt_s cn63xxp1; }; union cvmx_mixx_irhwm { @@ -154,30 +129,21 @@ union cvmx_mixx_irhwm { struct cvmx_mixx_irhwm_s cn52xxp1; struct cvmx_mixx_irhwm_s cn56xx; struct cvmx_mixx_irhwm_s cn56xxp1; - struct cvmx_mixx_irhwm_s cn63xx; - struct cvmx_mixx_irhwm_s cn63xxp1; }; union cvmx_mixx_iring1 { uint64_t u64; struct cvmx_mixx_iring1_s { - uint64_t reserved_60_63:4; - uint64_t isize:20; - uint64_t ibase:37; - uint64_t reserved_0_2:3; - } s; - struct cvmx_mixx_iring1_cn52xx { uint64_t reserved_60_63:4; uint64_t isize:20; uint64_t reserved_36_39:4; uint64_t ibase:33; uint64_t reserved_0_2:3; - } cn52xx; - struct cvmx_mixx_iring1_cn52xx cn52xxp1; - struct cvmx_mixx_iring1_cn52xx cn56xx; - struct cvmx_mixx_iring1_cn52xx cn56xxp1; - struct cvmx_mixx_iring1_s cn63xx; - struct cvmx_mixx_iring1_s cn63xxp1; + } s; + struct cvmx_mixx_iring1_s cn52xx; + struct cvmx_mixx_iring1_s cn52xxp1; + struct cvmx_mixx_iring1_s cn56xx; + struct cvmx_mixx_iring1_s cn56xxp1; }; union cvmx_mixx_iring2 { @@ -192,24 +158,11 @@ union cvmx_mixx_iring2 { struct cvmx_mixx_iring2_s cn52xxp1; struct cvmx_mixx_iring2_s cn56xx; struct cvmx_mixx_iring2_s cn56xxp1; - struct cvmx_mixx_iring2_s cn63xx; - struct cvmx_mixx_iring2_s cn63xxp1; }; union cvmx_mixx_isr { uint64_t u64; struct cvmx_mixx_isr_s { - uint64_t reserved_8_63:56; - uint64_t ts:1; - uint64_t orun:1; - uint64_t irun:1; - uint64_t data_drp:1; - uint64_t irthresh:1; - uint64_t orthresh:1; - uint64_t idblovf:1; - uint64_t odblovf:1; - } s; - struct cvmx_mixx_isr_cn52xx { uint64_t reserved_7_63:57; uint64_t orun:1; uint64_t irun:1; @@ -218,12 +171,11 @@ union cvmx_mixx_isr { uint64_t orthresh:1; uint64_t idblovf:1; uint64_t odblovf:1; - } cn52xx; - struct cvmx_mixx_isr_cn52xx cn52xxp1; - struct cvmx_mixx_isr_cn52xx cn56xx; - struct cvmx_mixx_isr_cn52xx cn56xxp1; - struct cvmx_mixx_isr_s cn63xx; - struct cvmx_mixx_isr_s cn63xxp1; + } s; + struct cvmx_mixx_isr_s cn52xx; + struct cvmx_mixx_isr_s cn52xxp1; + struct cvmx_mixx_isr_s cn56xx; + struct cvmx_mixx_isr_s cn56xxp1; }; union cvmx_mixx_orcnt { @@ -236,8 +188,6 @@ union cvmx_mixx_orcnt { struct cvmx_mixx_orcnt_s cn52xxp1; struct cvmx_mixx_orcnt_s cn56xx; struct cvmx_mixx_orcnt_s cn56xxp1; - struct cvmx_mixx_orcnt_s cn63xx; - struct cvmx_mixx_orcnt_s cn63xxp1; }; union cvmx_mixx_orhwm { @@ -250,30 +200,21 @@ union cvmx_mixx_orhwm { struct cvmx_mixx_orhwm_s cn52xxp1; struct cvmx_mixx_orhwm_s cn56xx; struct cvmx_mixx_orhwm_s cn56xxp1; - struct cvmx_mixx_orhwm_s cn63xx; - struct cvmx_mixx_orhwm_s cn63xxp1; }; union cvmx_mixx_oring1 { uint64_t u64; struct cvmx_mixx_oring1_s { - uint64_t reserved_60_63:4; - uint64_t osize:20; - uint64_t obase:37; - uint64_t reserved_0_2:3; - } s; - struct cvmx_mixx_oring1_cn52xx { uint64_t reserved_60_63:4; uint64_t osize:20; uint64_t reserved_36_39:4; uint64_t obase:33; uint64_t reserved_0_2:3; - } cn52xx; - struct cvmx_mixx_oring1_cn52xx cn52xxp1; - struct cvmx_mixx_oring1_cn52xx cn56xx; - struct cvmx_mixx_oring1_cn52xx cn56xxp1; - struct cvmx_mixx_oring1_s cn63xx; - struct cvmx_mixx_oring1_s cn63xxp1; + } s; + struct cvmx_mixx_oring1_s cn52xx; + struct cvmx_mixx_oring1_s cn52xxp1; + struct cvmx_mixx_oring1_s cn56xx; + struct cvmx_mixx_oring1_s cn56xxp1; }; union cvmx_mixx_oring2 { @@ -288,8 +229,6 @@ union cvmx_mixx_oring2 { struct cvmx_mixx_oring2_s cn52xxp1; struct cvmx_mixx_oring2_s cn56xx; struct cvmx_mixx_oring2_s cn56xxp1; - struct cvmx_mixx_oring2_s cn63xx; - struct cvmx_mixx_oring2_s cn63xxp1; }; union cvmx_mixx_remcnt { @@ -304,31 +243,6 @@ union cvmx_mixx_remcnt { struct cvmx_mixx_remcnt_s cn52xxp1; struct cvmx_mixx_remcnt_s cn56xx; struct cvmx_mixx_remcnt_s cn56xxp1; - struct cvmx_mixx_remcnt_s cn63xx; - struct cvmx_mixx_remcnt_s cn63xxp1; -}; - -union cvmx_mixx_tsctl { - uint64_t u64; - struct cvmx_mixx_tsctl_s { - uint64_t reserved_21_63:43; - uint64_t tsavl:5; - uint64_t reserved_13_15:3; - uint64_t tstot:5; - uint64_t reserved_5_7:3; - uint64_t tscnt:5; - } s; - struct cvmx_mixx_tsctl_s cn63xx; - struct cvmx_mixx_tsctl_s cn63xxp1; -}; - -union cvmx_mixx_tstamp { - uint64_t u64; - struct cvmx_mixx_tstamp_s { - uint64_t tstamp:64; - } s; - struct cvmx_mixx_tstamp_s cn63xx; - struct cvmx_mixx_tstamp_s cn63xxp1; }; #endif diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-npei-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-npei-defs.h index 9899a9d2ba72..4b347bb8ce80 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-npei-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-npei-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,114 +28,206 @@ #ifndef __CVMX_NPEI_DEFS_H__ #define __CVMX_NPEI_DEFS_H__ -#define CVMX_NPEI_BAR1_INDEXX(offset) (0x0000000000000000ull + ((offset) & 31) * 16) -#define CVMX_NPEI_BIST_STATUS (0x0000000000000580ull) -#define CVMX_NPEI_BIST_STATUS2 (0x0000000000000680ull) -#define CVMX_NPEI_CTL_PORT0 (0x0000000000000250ull) -#define CVMX_NPEI_CTL_PORT1 (0x0000000000000260ull) -#define CVMX_NPEI_CTL_STATUS (0x0000000000000570ull) -#define CVMX_NPEI_CTL_STATUS2 (0x0000000000003C00ull) -#define CVMX_NPEI_DATA_OUT_CNT (0x00000000000005F0ull) -#define CVMX_NPEI_DBG_DATA (0x0000000000000510ull) -#define CVMX_NPEI_DBG_SELECT (0x0000000000000500ull) -#define CVMX_NPEI_DMA0_INT_LEVEL (0x00000000000005C0ull) -#define CVMX_NPEI_DMA1_INT_LEVEL (0x00000000000005D0ull) -#define CVMX_NPEI_DMAX_COUNTS(offset) (0x0000000000000450ull + ((offset) & 7) * 16) -#define CVMX_NPEI_DMAX_DBELL(offset) (0x00000000000003B0ull + ((offset) & 7) * 16) -#define CVMX_NPEI_DMAX_IBUFF_SADDR(offset) (0x0000000000000400ull + ((offset) & 7) * 16) -#define CVMX_NPEI_DMAX_NADDR(offset) (0x00000000000004A0ull + ((offset) & 7) * 16) -#define CVMX_NPEI_DMA_CNTS (0x00000000000005E0ull) -#define CVMX_NPEI_DMA_CONTROL (0x00000000000003A0ull) -#define CVMX_NPEI_DMA_PCIE_REQ_NUM (0x00000000000005B0ull) -#define CVMX_NPEI_DMA_STATE1 (0x00000000000006C0ull) -#define CVMX_NPEI_DMA_STATE1_P1 (0x0000000000000680ull) -#define CVMX_NPEI_DMA_STATE2 (0x00000000000006D0ull) -#define CVMX_NPEI_DMA_STATE2_P1 (0x0000000000000690ull) -#define CVMX_NPEI_DMA_STATE3_P1 (0x00000000000006A0ull) -#define CVMX_NPEI_DMA_STATE4_P1 (0x00000000000006B0ull) -#define CVMX_NPEI_DMA_STATE5_P1 (0x00000000000006C0ull) -#define CVMX_NPEI_INT_A_ENB (0x0000000000000560ull) -#define CVMX_NPEI_INT_A_ENB2 (0x0000000000003CE0ull) -#define CVMX_NPEI_INT_A_SUM (0x0000000000000550ull) -#define CVMX_NPEI_INT_ENB (0x0000000000000540ull) -#define CVMX_NPEI_INT_ENB2 (0x0000000000003CD0ull) -#define CVMX_NPEI_INT_INFO (0x0000000000000590ull) -#define CVMX_NPEI_INT_SUM (0x0000000000000530ull) -#define CVMX_NPEI_INT_SUM2 (0x0000000000003CC0ull) -#define CVMX_NPEI_LAST_WIN_RDATA0 (0x0000000000000600ull) -#define CVMX_NPEI_LAST_WIN_RDATA1 (0x0000000000000610ull) -#define CVMX_NPEI_MEM_ACCESS_CTL (0x00000000000004F0ull) -#define CVMX_NPEI_MEM_ACCESS_SUBIDX(offset) (0x0000000000000340ull + ((offset) & 31) * 16 - 16*12) -#define CVMX_NPEI_MSI_ENB0 (0x0000000000003C50ull) -#define CVMX_NPEI_MSI_ENB1 (0x0000000000003C60ull) -#define CVMX_NPEI_MSI_ENB2 (0x0000000000003C70ull) -#define CVMX_NPEI_MSI_ENB3 (0x0000000000003C80ull) -#define CVMX_NPEI_MSI_RCV0 (0x0000000000003C10ull) -#define CVMX_NPEI_MSI_RCV1 (0x0000000000003C20ull) -#define CVMX_NPEI_MSI_RCV2 (0x0000000000003C30ull) -#define CVMX_NPEI_MSI_RCV3 (0x0000000000003C40ull) -#define CVMX_NPEI_MSI_RD_MAP (0x0000000000003CA0ull) -#define CVMX_NPEI_MSI_W1C_ENB0 (0x0000000000003CF0ull) -#define CVMX_NPEI_MSI_W1C_ENB1 (0x0000000000003D00ull) -#define CVMX_NPEI_MSI_W1C_ENB2 (0x0000000000003D10ull) -#define CVMX_NPEI_MSI_W1C_ENB3 (0x0000000000003D20ull) -#define CVMX_NPEI_MSI_W1S_ENB0 (0x0000000000003D30ull) -#define CVMX_NPEI_MSI_W1S_ENB1 (0x0000000000003D40ull) -#define CVMX_NPEI_MSI_W1S_ENB2 (0x0000000000003D50ull) -#define CVMX_NPEI_MSI_W1S_ENB3 (0x0000000000003D60ull) -#define CVMX_NPEI_MSI_WR_MAP (0x0000000000003C90ull) -#define CVMX_NPEI_PCIE_CREDIT_CNT (0x0000000000003D70ull) -#define CVMX_NPEI_PCIE_MSI_RCV (0x0000000000003CB0ull) -#define CVMX_NPEI_PCIE_MSI_RCV_B1 (0x0000000000000650ull) -#define CVMX_NPEI_PCIE_MSI_RCV_B2 (0x0000000000000660ull) -#define CVMX_NPEI_PCIE_MSI_RCV_B3 (0x0000000000000670ull) -#define CVMX_NPEI_PKTX_CNTS(offset) (0x0000000000002400ull + ((offset) & 31) * 16) -#define CVMX_NPEI_PKTX_INSTR_BADDR(offset) (0x0000000000002800ull + ((offset) & 31) * 16) -#define CVMX_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) (0x0000000000002C00ull + ((offset) & 31) * 16) -#define CVMX_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) (0x0000000000003000ull + ((offset) & 31) * 16) -#define CVMX_NPEI_PKTX_INSTR_HEADER(offset) (0x0000000000003400ull + ((offset) & 31) * 16) -#define CVMX_NPEI_PKTX_IN_BP(offset) (0x0000000000003800ull + ((offset) & 31) * 16) -#define CVMX_NPEI_PKTX_SLIST_BADDR(offset) (0x0000000000001400ull + ((offset) & 31) * 16) -#define CVMX_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) (0x0000000000001800ull + ((offset) & 31) * 16) -#define CVMX_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) (0x0000000000001C00ull + ((offset) & 31) * 16) -#define CVMX_NPEI_PKT_CNT_INT (0x0000000000001110ull) -#define CVMX_NPEI_PKT_CNT_INT_ENB (0x0000000000001130ull) -#define CVMX_NPEI_PKT_DATA_OUT_ES (0x00000000000010B0ull) -#define CVMX_NPEI_PKT_DATA_OUT_NS (0x00000000000010A0ull) -#define CVMX_NPEI_PKT_DATA_OUT_ROR (0x0000000000001090ull) -#define CVMX_NPEI_PKT_DPADDR (0x0000000000001080ull) -#define CVMX_NPEI_PKT_INPUT_CONTROL (0x0000000000001150ull) -#define CVMX_NPEI_PKT_INSTR_ENB (0x0000000000001000ull) -#define CVMX_NPEI_PKT_INSTR_RD_SIZE (0x0000000000001190ull) -#define CVMX_NPEI_PKT_INSTR_SIZE (0x0000000000001020ull) -#define CVMX_NPEI_PKT_INT_LEVELS (0x0000000000001100ull) -#define CVMX_NPEI_PKT_IN_BP (0x00000000000006B0ull) -#define CVMX_NPEI_PKT_IN_DONEX_CNTS(offset) (0x0000000000002000ull + ((offset) & 31) * 16) -#define CVMX_NPEI_PKT_IN_INSTR_COUNTS (0x00000000000006A0ull) -#define CVMX_NPEI_PKT_IN_PCIE_PORT (0x00000000000011A0ull) -#define CVMX_NPEI_PKT_IPTR (0x0000000000001070ull) -#define CVMX_NPEI_PKT_OUTPUT_WMARK (0x0000000000001160ull) -#define CVMX_NPEI_PKT_OUT_BMODE (0x00000000000010D0ull) -#define CVMX_NPEI_PKT_OUT_ENB (0x0000000000001010ull) -#define CVMX_NPEI_PKT_PCIE_PORT (0x00000000000010E0ull) -#define CVMX_NPEI_PKT_PORT_IN_RST (0x0000000000000690ull) -#define CVMX_NPEI_PKT_SLIST_ES (0x0000000000001050ull) -#define CVMX_NPEI_PKT_SLIST_ID_SIZE (0x0000000000001180ull) -#define CVMX_NPEI_PKT_SLIST_NS (0x0000000000001040ull) -#define CVMX_NPEI_PKT_SLIST_ROR (0x0000000000001030ull) -#define CVMX_NPEI_PKT_TIME_INT (0x0000000000001120ull) -#define CVMX_NPEI_PKT_TIME_INT_ENB (0x0000000000001140ull) -#define CVMX_NPEI_RSL_INT_BLOCKS (0x0000000000000520ull) -#define CVMX_NPEI_SCRATCH_1 (0x0000000000000270ull) -#define CVMX_NPEI_STATE1 (0x0000000000000620ull) -#define CVMX_NPEI_STATE2 (0x0000000000000630ull) -#define CVMX_NPEI_STATE3 (0x0000000000000640ull) -#define CVMX_NPEI_WINDOW_CTL (0x0000000000000380ull) -#define CVMX_NPEI_WIN_RD_ADDR (0x0000000000000210ull) -#define CVMX_NPEI_WIN_RD_DATA (0x0000000000000240ull) -#define CVMX_NPEI_WIN_WR_ADDR (0x0000000000000200ull) -#define CVMX_NPEI_WIN_WR_DATA (0x0000000000000220ull) -#define CVMX_NPEI_WIN_WR_MASK (0x0000000000000230ull) +#define CVMX_NPEI_BAR1_INDEXX(offset) \ + (0x0000000000000000ull + (((offset) & 31) * 16)) +#define CVMX_NPEI_BIST_STATUS \ + (0x0000000000000580ull) +#define CVMX_NPEI_BIST_STATUS2 \ + (0x0000000000000680ull) +#define CVMX_NPEI_CTL_PORT0 \ + (0x0000000000000250ull) +#define CVMX_NPEI_CTL_PORT1 \ + (0x0000000000000260ull) +#define CVMX_NPEI_CTL_STATUS \ + (0x0000000000000570ull) +#define CVMX_NPEI_CTL_STATUS2 \ + (0x0000000000003C00ull) +#define CVMX_NPEI_DATA_OUT_CNT \ + (0x00000000000005F0ull) +#define CVMX_NPEI_DBG_DATA \ + (0x0000000000000510ull) +#define CVMX_NPEI_DBG_SELECT \ + (0x0000000000000500ull) +#define CVMX_NPEI_DMA0_INT_LEVEL \ + (0x00000000000005C0ull) +#define CVMX_NPEI_DMA1_INT_LEVEL \ + (0x00000000000005D0ull) +#define CVMX_NPEI_DMAX_COUNTS(offset) \ + (0x0000000000000450ull + (((offset) & 7) * 16)) +#define CVMX_NPEI_DMAX_DBELL(offset) \ + (0x00000000000003B0ull + (((offset) & 7) * 16)) +#define CVMX_NPEI_DMAX_IBUFF_SADDR(offset) \ + (0x0000000000000400ull + (((offset) & 7) * 16)) +#define CVMX_NPEI_DMAX_NADDR(offset) \ + (0x00000000000004A0ull + (((offset) & 7) * 16)) +#define CVMX_NPEI_DMA_CNTS \ + (0x00000000000005E0ull) +#define CVMX_NPEI_DMA_CONTROL \ + (0x00000000000003A0ull) +#define CVMX_NPEI_INT_A_ENB \ + (0x0000000000000560ull) +#define CVMX_NPEI_INT_A_ENB2 \ + (0x0000000000003CE0ull) +#define CVMX_NPEI_INT_A_SUM \ + (0x0000000000000550ull) +#define CVMX_NPEI_INT_ENB \ + (0x0000000000000540ull) +#define CVMX_NPEI_INT_ENB2 \ + (0x0000000000003CD0ull) +#define CVMX_NPEI_INT_INFO \ + (0x0000000000000590ull) +#define CVMX_NPEI_INT_SUM \ + (0x0000000000000530ull) +#define CVMX_NPEI_INT_SUM2 \ + (0x0000000000003CC0ull) +#define CVMX_NPEI_LAST_WIN_RDATA0 \ + (0x0000000000000600ull) +#define CVMX_NPEI_LAST_WIN_RDATA1 \ + (0x0000000000000610ull) +#define CVMX_NPEI_MEM_ACCESS_CTL \ + (0x00000000000004F0ull) +#define CVMX_NPEI_MEM_ACCESS_SUBIDX(offset) \ + (0x0000000000000340ull + (((offset) & 31) * 16) - 16 * 12) +#define CVMX_NPEI_MSI_ENB0 \ + (0x0000000000003C50ull) +#define CVMX_NPEI_MSI_ENB1 \ + (0x0000000000003C60ull) +#define CVMX_NPEI_MSI_ENB2 \ + (0x0000000000003C70ull) +#define CVMX_NPEI_MSI_ENB3 \ + (0x0000000000003C80ull) +#define CVMX_NPEI_MSI_RCV0 \ + (0x0000000000003C10ull) +#define CVMX_NPEI_MSI_RCV1 \ + (0x0000000000003C20ull) +#define CVMX_NPEI_MSI_RCV2 \ + (0x0000000000003C30ull) +#define CVMX_NPEI_MSI_RCV3 \ + (0x0000000000003C40ull) +#define CVMX_NPEI_MSI_RD_MAP \ + (0x0000000000003CA0ull) +#define CVMX_NPEI_MSI_W1C_ENB0 \ + (0x0000000000003CF0ull) +#define CVMX_NPEI_MSI_W1C_ENB1 \ + (0x0000000000003D00ull) +#define CVMX_NPEI_MSI_W1C_ENB2 \ + (0x0000000000003D10ull) +#define CVMX_NPEI_MSI_W1C_ENB3 \ + (0x0000000000003D20ull) +#define CVMX_NPEI_MSI_W1S_ENB0 \ + (0x0000000000003D30ull) +#define CVMX_NPEI_MSI_W1S_ENB1 \ + (0x0000000000003D40ull) +#define CVMX_NPEI_MSI_W1S_ENB2 \ + (0x0000000000003D50ull) +#define CVMX_NPEI_MSI_W1S_ENB3 \ + (0x0000000000003D60ull) +#define CVMX_NPEI_MSI_WR_MAP \ + (0x0000000000003C90ull) +#define CVMX_NPEI_PCIE_CREDIT_CNT \ + (0x0000000000003D70ull) +#define CVMX_NPEI_PCIE_MSI_RCV \ + (0x0000000000003CB0ull) +#define CVMX_NPEI_PCIE_MSI_RCV_B1 \ + (0x0000000000000650ull) +#define CVMX_NPEI_PCIE_MSI_RCV_B2 \ + (0x0000000000000660ull) +#define CVMX_NPEI_PCIE_MSI_RCV_B3 \ + (0x0000000000000670ull) +#define CVMX_NPEI_PKTX_CNTS(offset) \ + (0x0000000000002400ull + (((offset) & 31) * 16)) +#define CVMX_NPEI_PKTX_INSTR_BADDR(offset) \ + (0x0000000000002800ull + (((offset) & 31) * 16)) +#define CVMX_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) \ + (0x0000000000002C00ull + (((offset) & 31) * 16)) +#define CVMX_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) \ + (0x0000000000003000ull + (((offset) & 31) * 16)) +#define CVMX_NPEI_PKTX_INSTR_HEADER(offset) \ + (0x0000000000003400ull + (((offset) & 31) * 16)) +#define CVMX_NPEI_PKTX_IN_BP(offset) \ + (0x0000000000003800ull + (((offset) & 31) * 16)) +#define CVMX_NPEI_PKTX_SLIST_BADDR(offset) \ + (0x0000000000001400ull + (((offset) & 31) * 16)) +#define CVMX_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) \ + (0x0000000000001800ull + (((offset) & 31) * 16)) +#define CVMX_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) \ + (0x0000000000001C00ull + (((offset) & 31) * 16)) +#define CVMX_NPEI_PKT_CNT_INT \ + (0x0000000000001110ull) +#define CVMX_NPEI_PKT_CNT_INT_ENB \ + (0x0000000000001130ull) +#define CVMX_NPEI_PKT_DATA_OUT_ES \ + (0x00000000000010B0ull) +#define CVMX_NPEI_PKT_DATA_OUT_NS \ + (0x00000000000010A0ull) +#define CVMX_NPEI_PKT_DATA_OUT_ROR \ + (0x0000000000001090ull) +#define CVMX_NPEI_PKT_DPADDR \ + (0x0000000000001080ull) +#define CVMX_NPEI_PKT_INPUT_CONTROL \ + (0x0000000000001150ull) +#define CVMX_NPEI_PKT_INSTR_ENB \ + (0x0000000000001000ull) +#define CVMX_NPEI_PKT_INSTR_RD_SIZE \ + (0x0000000000001190ull) +#define CVMX_NPEI_PKT_INSTR_SIZE \ + (0x0000000000001020ull) +#define CVMX_NPEI_PKT_INT_LEVELS \ + (0x0000000000001100ull) +#define CVMX_NPEI_PKT_IN_BP \ + (0x00000000000006B0ull) +#define CVMX_NPEI_PKT_IN_DONEX_CNTS(offset) \ + (0x0000000000002000ull + (((offset) & 31) * 16)) +#define CVMX_NPEI_PKT_IN_INSTR_COUNTS \ + (0x00000000000006A0ull) +#define CVMX_NPEI_PKT_IN_PCIE_PORT \ + (0x00000000000011A0ull) +#define CVMX_NPEI_PKT_IPTR \ + (0x0000000000001070ull) +#define CVMX_NPEI_PKT_OUTPUT_WMARK \ + (0x0000000000001160ull) +#define CVMX_NPEI_PKT_OUT_BMODE \ + (0x00000000000010D0ull) +#define CVMX_NPEI_PKT_OUT_ENB \ + (0x0000000000001010ull) +#define CVMX_NPEI_PKT_PCIE_PORT \ + (0x00000000000010E0ull) +#define CVMX_NPEI_PKT_PORT_IN_RST \ + (0x0000000000000690ull) +#define CVMX_NPEI_PKT_SLIST_ES \ + (0x0000000000001050ull) +#define CVMX_NPEI_PKT_SLIST_ID_SIZE \ + (0x0000000000001180ull) +#define CVMX_NPEI_PKT_SLIST_NS \ + (0x0000000000001040ull) +#define CVMX_NPEI_PKT_SLIST_ROR \ + (0x0000000000001030ull) +#define CVMX_NPEI_PKT_TIME_INT \ + (0x0000000000001120ull) +#define CVMX_NPEI_PKT_TIME_INT_ENB \ + (0x0000000000001140ull) +#define CVMX_NPEI_RSL_INT_BLOCKS \ + (0x0000000000000520ull) +#define CVMX_NPEI_SCRATCH_1 \ + (0x0000000000000270ull) +#define CVMX_NPEI_STATE1 \ + (0x0000000000000620ull) +#define CVMX_NPEI_STATE2 \ + (0x0000000000000630ull) +#define CVMX_NPEI_STATE3 \ + (0x0000000000000640ull) +#define CVMX_NPEI_WINDOW_CTL \ + (0x0000000000000380ull) +#define CVMX_NPEI_WIN_RD_ADDR \ + (0x0000000000000210ull) +#define CVMX_NPEI_WIN_RD_DATA \ + (0x0000000000000240ull) +#define CVMX_NPEI_WIN_WR_ADDR \ + (0x0000000000000200ull) +#define CVMX_NPEI_WIN_WR_DATA \ + (0x0000000000000220ull) +#define CVMX_NPEI_WIN_WR_MASK \ + (0x0000000000000230ull) union cvmx_npei_bar1_indexx { uint32_t u32; @@ -156,7 +248,9 @@ union cvmx_npei_bist_status { uint64_t u64; struct cvmx_npei_bist_status_s { uint64_t pkt_rdf:1; - uint64_t reserved_60_62:3; + uint64_t pkt_pmem:1; + uint64_t pkt_p1:1; + uint64_t reserved_60_60:1; uint64_t pcr_gim:1; uint64_t pkt_pif:1; uint64_t pcsr_int:1; @@ -207,7 +301,9 @@ union cvmx_npei_bist_status { } s; struct cvmx_npei_bist_status_cn52xx { uint64_t pkt_rdf:1; - uint64_t reserved_60_62:3; + uint64_t pkt_pmem:1; + uint64_t pkt_p1:1; + uint64_t reserved_60_60:1; uint64_t pcr_gim:1; uint64_t pkt_pif:1; uint64_t pcsr_int:1; @@ -314,7 +410,66 @@ union cvmx_npei_bist_status { uint64_t msi:1; uint64_t ncb_cmd:1; } cn52xxp1; - struct cvmx_npei_bist_status_cn52xx cn56xx; + struct cvmx_npei_bist_status_cn56xx { + uint64_t pkt_rdf:1; + uint64_t reserved_60_62:3; + uint64_t pcr_gim:1; + uint64_t pkt_pif:1; + uint64_t pcsr_int:1; + uint64_t pcsr_im:1; + uint64_t pcsr_cnt:1; + uint64_t pcsr_id:1; + uint64_t pcsr_sl:1; + uint64_t pkt_imem:1; + uint64_t pkt_pfm:1; + uint64_t pkt_pof:1; + uint64_t reserved_48_49:2; + uint64_t pkt_pop0:1; + uint64_t pkt_pop1:1; + uint64_t d0_mem:1; + uint64_t d1_mem:1; + uint64_t d2_mem:1; + uint64_t d3_mem:1; + uint64_t d4_mem:1; + uint64_t ds_mem:1; + uint64_t reserved_36_39:4; + uint64_t d0_pst:1; + uint64_t d1_pst:1; + uint64_t d2_pst:1; + uint64_t d3_pst:1; + uint64_t d4_pst:1; + uint64_t n2p0_c:1; + uint64_t n2p0_o:1; + uint64_t n2p1_c:1; + uint64_t n2p1_o:1; + uint64_t cpl_p0:1; + uint64_t cpl_p1:1; + uint64_t p2n1_po:1; + uint64_t p2n1_no:1; + uint64_t p2n1_co:1; + uint64_t p2n0_po:1; + uint64_t p2n0_no:1; + uint64_t p2n0_co:1; + uint64_t p2n0_c0:1; + uint64_t p2n0_c1:1; + uint64_t p2n0_n:1; + uint64_t p2n0_p0:1; + uint64_t p2n0_p1:1; + uint64_t p2n1_c0:1; + uint64_t p2n1_c1:1; + uint64_t p2n1_n:1; + uint64_t p2n1_p0:1; + uint64_t p2n1_p1:1; + uint64_t csm0:1; + uint64_t csm1:1; + uint64_t dif0:1; + uint64_t dif1:1; + uint64_t dif2:1; + uint64_t dif3:1; + uint64_t dif4:1; + uint64_t msi:1; + uint64_t ncb_cmd:1; + } cn56xx; struct cvmx_npei_bist_status_cn56xxp1 { uint64_t reserved_58_63:6; uint64_t pcsr_int:1; @@ -381,16 +536,7 @@ union cvmx_npei_bist_status { union cvmx_npei_bist_status2 { uint64_t u64; struct cvmx_npei_bist_status2_s { - uint64_t reserved_14_63:50; - uint64_t prd_tag:1; - uint64_t prd_st0:1; - uint64_t prd_st1:1; - uint64_t prd_err:1; - uint64_t nrd_st:1; - uint64_t nwe_st:1; - uint64_t nwe_wr0:1; - uint64_t nwe_wr1:1; - uint64_t pkt_rd:1; + uint64_t reserved_5_63:59; uint64_t psc_p0:1; uint64_t psc_p1:1; uint64_t pkt_gd:1; @@ -484,7 +630,8 @@ union cvmx_npei_ctl_status { } cn52xxp1; struct cvmx_npei_ctl_status_s cn56xx; struct cvmx_npei_ctl_status_cn56xxp1 { - uint64_t reserved_15_63:49; + uint64_t reserved_16_63:48; + uint64_t ring_en:1; uint64_t lnk_rst:1; uint64_t arb:1; uint64_t pkt_bp:4; @@ -609,14 +756,14 @@ union cvmx_npei_dmax_ibuff_saddr { uint64_t saddr:29; uint64_t reserved_0_6:7; } s; - struct cvmx_npei_dmax_ibuff_saddr_s cn52xx; - struct cvmx_npei_dmax_ibuff_saddr_cn52xxp1 { + struct cvmx_npei_dmax_ibuff_saddr_cn52xx { uint64_t reserved_36_63:28; uint64_t saddr:29; uint64_t reserved_0_6:7; - } cn52xxp1; + } cn52xx; + struct cvmx_npei_dmax_ibuff_saddr_cn52xx cn52xxp1; struct cvmx_npei_dmax_ibuff_saddr_s cn56xx; - struct cvmx_npei_dmax_ibuff_saddr_cn52xxp1 cn56xxp1; + struct cvmx_npei_dmax_ibuff_saddr_cn52xx cn56xxp1; }; union cvmx_npei_dmax_naddr { @@ -670,8 +817,7 @@ union cvmx_npei_dma_cnts { union cvmx_npei_dma_control { uint64_t u64; struct cvmx_npei_dma_control_s { - uint64_t reserved_40_63:24; - uint64_t p_32b_m:1; + uint64_t reserved_39_63:25; uint64_t dma4_enb:1; uint64_t dma3_enb:1; uint64_t dma2_enb:1; @@ -707,161 +853,7 @@ union cvmx_npei_dma_control { uint64_t csize:14; } cn52xxp1; struct cvmx_npei_dma_control_s cn56xx; - struct cvmx_npei_dma_control_cn56xxp1 { - uint64_t reserved_39_63:25; - uint64_t dma4_enb:1; - uint64_t dma3_enb:1; - uint64_t dma2_enb:1; - uint64_t dma1_enb:1; - uint64_t dma0_enb:1; - uint64_t b0_lend:1; - uint64_t dwb_denb:1; - uint64_t dwb_ichk:9; - uint64_t fpa_que:3; - uint64_t o_add1:1; - uint64_t o_ro:1; - uint64_t o_ns:1; - uint64_t o_es:2; - uint64_t o_mode:1; - uint64_t csize:14; - } cn56xxp1; -}; - -union cvmx_npei_dma_pcie_req_num { - uint64_t u64; - struct cvmx_npei_dma_pcie_req_num_s { - uint64_t dma_arb:1; - uint64_t reserved_53_62:10; - uint64_t pkt_cnt:5; - uint64_t reserved_45_47:3; - uint64_t dma4_cnt:5; - uint64_t reserved_37_39:3; - uint64_t dma3_cnt:5; - uint64_t reserved_29_31:3; - uint64_t dma2_cnt:5; - uint64_t reserved_21_23:3; - uint64_t dma1_cnt:5; - uint64_t reserved_13_15:3; - uint64_t dma0_cnt:5; - uint64_t reserved_5_7:3; - uint64_t dma_cnt:5; - } s; - struct cvmx_npei_dma_pcie_req_num_s cn52xx; - struct cvmx_npei_dma_pcie_req_num_s cn56xx; -}; - -union cvmx_npei_dma_state1 { - uint64_t u64; - struct cvmx_npei_dma_state1_s { - uint64_t reserved_40_63:24; - uint64_t d4_dwe:8; - uint64_t d3_dwe:8; - uint64_t d2_dwe:8; - uint64_t d1_dwe:8; - uint64_t d0_dwe:8; - } s; - struct cvmx_npei_dma_state1_s cn52xx; -}; - -union cvmx_npei_dma_state1_p1 { - uint64_t u64; - struct cvmx_npei_dma_state1_p1_s { - uint64_t reserved_60_63:4; - uint64_t d0_difst:7; - uint64_t d1_difst:7; - uint64_t d2_difst:7; - uint64_t d3_difst:7; - uint64_t d4_difst:7; - uint64_t d0_reqst:5; - uint64_t d1_reqst:5; - uint64_t d2_reqst:5; - uint64_t d3_reqst:5; - uint64_t d4_reqst:5; - } s; - struct cvmx_npei_dma_state1_p1_cn52xxp1 { - uint64_t reserved_60_63:4; - uint64_t d0_difst:7; - uint64_t d1_difst:7; - uint64_t d2_difst:7; - uint64_t d3_difst:7; - uint64_t reserved_25_31:7; - uint64_t d0_reqst:5; - uint64_t d1_reqst:5; - uint64_t d2_reqst:5; - uint64_t d3_reqst:5; - uint64_t reserved_0_4:5; - } cn52xxp1; - struct cvmx_npei_dma_state1_p1_s cn56xxp1; -}; - -union cvmx_npei_dma_state2 { - uint64_t u64; - struct cvmx_npei_dma_state2_s { - uint64_t reserved_28_63:36; - uint64_t ndwe:4; - uint64_t reserved_21_23:3; - uint64_t ndre:5; - uint64_t reserved_10_15:6; - uint64_t prd:10; - } s; - struct cvmx_npei_dma_state2_s cn52xx; -}; - -union cvmx_npei_dma_state2_p1 { - uint64_t u64; - struct cvmx_npei_dma_state2_p1_s { - uint64_t reserved_45_63:19; - uint64_t d0_dffst:9; - uint64_t d1_dffst:9; - uint64_t d2_dffst:9; - uint64_t d3_dffst:9; - uint64_t d4_dffst:9; - } s; - struct cvmx_npei_dma_state2_p1_cn52xxp1 { - uint64_t reserved_45_63:19; - uint64_t d0_dffst:9; - uint64_t d1_dffst:9; - uint64_t d2_dffst:9; - uint64_t d3_dffst:9; - uint64_t reserved_0_8:9; - } cn52xxp1; - struct cvmx_npei_dma_state2_p1_s cn56xxp1; -}; - -union cvmx_npei_dma_state3_p1 { - uint64_t u64; - struct cvmx_npei_dma_state3_p1_s { - uint64_t reserved_60_63:4; - uint64_t d0_drest:15; - uint64_t d1_drest:15; - uint64_t d2_drest:15; - uint64_t d3_drest:15; - } s; - struct cvmx_npei_dma_state3_p1_s cn52xxp1; - struct cvmx_npei_dma_state3_p1_s cn56xxp1; -}; - -union cvmx_npei_dma_state4_p1 { - uint64_t u64; - struct cvmx_npei_dma_state4_p1_s { - uint64_t reserved_52_63:12; - uint64_t d0_dwest:13; - uint64_t d1_dwest:13; - uint64_t d2_dwest:13; - uint64_t d3_dwest:13; - } s; - struct cvmx_npei_dma_state4_p1_s cn52xxp1; - struct cvmx_npei_dma_state4_p1_s cn56xxp1; -}; - -union cvmx_npei_dma_state5_p1 { - uint64_t u64; - struct cvmx_npei_dma_state5_p1_s { - uint64_t reserved_28_63:36; - uint64_t d4_drest:15; - uint64_t d4_dwest:13; - } s; - struct cvmx_npei_dma_state5_p1_s cn56xxp1; + struct cvmx_npei_dma_control_s cn56xxp1; }; union cvmx_npei_int_a_enb { @@ -879,7 +871,17 @@ union cvmx_npei_int_a_enb { uint64_t dma1_cpl:1; uint64_t dma0_cpl:1; } s; - struct cvmx_npei_int_a_enb_s cn52xx; + struct cvmx_npei_int_a_enb_cn52xx { + uint64_t reserved_8_63:56; + uint64_t p1_rdlk:1; + uint64_t p0_rdlk:1; + uint64_t pgl_err:1; + uint64_t pdi_err:1; + uint64_t pop_err:1; + uint64_t pins_err:1; + uint64_t dma1_cpl:1; + uint64_t dma0_cpl:1; + } cn52xx; struct cvmx_npei_int_a_enb_cn52xxp1 { uint64_t reserved_2_63:62; uint64_t dma1_cpl:1; @@ -903,7 +905,16 @@ union cvmx_npei_int_a_enb2 { uint64_t dma1_cpl:1; uint64_t dma0_cpl:1; } s; - struct cvmx_npei_int_a_enb2_s cn52xx; + struct cvmx_npei_int_a_enb2_cn52xx { + uint64_t reserved_8_63:56; + uint64_t p1_rdlk:1; + uint64_t p0_rdlk:1; + uint64_t pgl_err:1; + uint64_t pdi_err:1; + uint64_t pop_err:1; + uint64_t pins_err:1; + uint64_t reserved_0_1:2; + } cn52xx; struct cvmx_npei_int_a_enb2_cn52xxp1 { uint64_t reserved_2_63:62; uint64_t dma1_cpl:1; @@ -927,7 +938,17 @@ union cvmx_npei_int_a_sum { uint64_t dma1_cpl:1; uint64_t dma0_cpl:1; } s; - struct cvmx_npei_int_a_sum_s cn52xx; + struct cvmx_npei_int_a_sum_cn52xx { + uint64_t reserved_8_63:56; + uint64_t p1_rdlk:1; + uint64_t p0_rdlk:1; + uint64_t pgl_err:1; + uint64_t pdi_err:1; + uint64_t pop_err:1; + uint64_t pins_err:1; + uint64_t dma1_cpl:1; + uint64_t dma0_cpl:1; + } cn52xx; struct cvmx_npei_int_a_sum_cn52xxp1 { uint64_t reserved_2_63:62; uint64_t dma1_cpl:1; @@ -1529,7 +1550,10 @@ union cvmx_npei_int_sum { uint64_t c0_se:1; uint64_t reserved_20_20:1; uint64_t c0_aeri:1; - uint64_t reserved_15_18:4; + uint64_t ptime:1; + uint64_t pcnt:1; + uint64_t pidbof:1; + uint64_t psldbof:1; uint64_t dtime1:1; uint64_t dtime0:1; uint64_t dcnt1:1; @@ -1935,6 +1959,7 @@ union cvmx_npei_pktx_cnts { } s; struct cvmx_npei_pktx_cnts_s cn52xx; struct cvmx_npei_pktx_cnts_s cn56xx; + struct cvmx_npei_pktx_cnts_s cn56xxp1; }; union cvmx_npei_pktx_in_bp { @@ -1945,6 +1970,7 @@ union cvmx_npei_pktx_in_bp { } s; struct cvmx_npei_pktx_in_bp_s cn52xx; struct cvmx_npei_pktx_in_bp_s cn56xx; + struct cvmx_npei_pktx_in_bp_s cn56xxp1; }; union cvmx_npei_pktx_instr_baddr { @@ -1955,6 +1981,7 @@ union cvmx_npei_pktx_instr_baddr { } s; struct cvmx_npei_pktx_instr_baddr_s cn52xx; struct cvmx_npei_pktx_instr_baddr_s cn56xx; + struct cvmx_npei_pktx_instr_baddr_s cn56xxp1; }; union cvmx_npei_pktx_instr_baoff_dbell { @@ -1965,6 +1992,7 @@ union cvmx_npei_pktx_instr_baoff_dbell { } s; struct cvmx_npei_pktx_instr_baoff_dbell_s cn52xx; struct cvmx_npei_pktx_instr_baoff_dbell_s cn56xx; + struct cvmx_npei_pktx_instr_baoff_dbell_s cn56xxp1; }; union cvmx_npei_pktx_instr_fifo_rsize { @@ -1978,6 +2006,7 @@ union cvmx_npei_pktx_instr_fifo_rsize { } s; struct cvmx_npei_pktx_instr_fifo_rsize_s cn52xx; struct cvmx_npei_pktx_instr_fifo_rsize_s cn56xx; + struct cvmx_npei_pktx_instr_fifo_rsize_s cn56xxp1; }; union cvmx_npei_pktx_instr_header { @@ -1985,20 +2014,21 @@ union cvmx_npei_pktx_instr_header { struct cvmx_npei_pktx_instr_header_s { uint64_t reserved_44_63:20; uint64_t pbp:1; - uint64_t reserved_38_42:5; + uint64_t rsv_f:5; uint64_t rparmode:2; - uint64_t reserved_35_35:1; + uint64_t rsv_e:1; uint64_t rskp_len:7; - uint64_t reserved_22_27:6; + uint64_t rsv_d:6; uint64_t use_ihdr:1; - uint64_t reserved_16_20:5; + uint64_t rsv_c:5; uint64_t par_mode:2; - uint64_t reserved_13_13:1; + uint64_t rsv_b:1; uint64_t skp_len:7; - uint64_t reserved_0_5:6; + uint64_t rsv_a:6; } s; struct cvmx_npei_pktx_instr_header_s cn52xx; struct cvmx_npei_pktx_instr_header_s cn56xx; + struct cvmx_npei_pktx_instr_header_s cn56xxp1; }; union cvmx_npei_pktx_slist_baddr { @@ -2009,6 +2039,7 @@ union cvmx_npei_pktx_slist_baddr { } s; struct cvmx_npei_pktx_slist_baddr_s cn52xx; struct cvmx_npei_pktx_slist_baddr_s cn56xx; + struct cvmx_npei_pktx_slist_baddr_s cn56xxp1; }; union cvmx_npei_pktx_slist_baoff_dbell { @@ -2019,6 +2050,7 @@ union cvmx_npei_pktx_slist_baoff_dbell { } s; struct cvmx_npei_pktx_slist_baoff_dbell_s cn52xx; struct cvmx_npei_pktx_slist_baoff_dbell_s cn56xx; + struct cvmx_npei_pktx_slist_baoff_dbell_s cn56xxp1; }; union cvmx_npei_pktx_slist_fifo_rsize { @@ -2029,6 +2061,7 @@ union cvmx_npei_pktx_slist_fifo_rsize { } s; struct cvmx_npei_pktx_slist_fifo_rsize_s cn52xx; struct cvmx_npei_pktx_slist_fifo_rsize_s cn56xx; + struct cvmx_npei_pktx_slist_fifo_rsize_s cn56xxp1; }; union cvmx_npei_pkt_cnt_int { @@ -2039,6 +2072,7 @@ union cvmx_npei_pkt_cnt_int { } s; struct cvmx_npei_pkt_cnt_int_s cn52xx; struct cvmx_npei_pkt_cnt_int_s cn56xx; + struct cvmx_npei_pkt_cnt_int_s cn56xxp1; }; union cvmx_npei_pkt_cnt_int_enb { @@ -2049,6 +2083,7 @@ union cvmx_npei_pkt_cnt_int_enb { } s; struct cvmx_npei_pkt_cnt_int_enb_s cn52xx; struct cvmx_npei_pkt_cnt_int_enb_s cn56xx; + struct cvmx_npei_pkt_cnt_int_enb_s cn56xxp1; }; union cvmx_npei_pkt_data_out_es { @@ -2058,6 +2093,7 @@ union cvmx_npei_pkt_data_out_es { } s; struct cvmx_npei_pkt_data_out_es_s cn52xx; struct cvmx_npei_pkt_data_out_es_s cn56xx; + struct cvmx_npei_pkt_data_out_es_s cn56xxp1; }; union cvmx_npei_pkt_data_out_ns { @@ -2068,6 +2104,7 @@ union cvmx_npei_pkt_data_out_ns { } s; struct cvmx_npei_pkt_data_out_ns_s cn52xx; struct cvmx_npei_pkt_data_out_ns_s cn56xx; + struct cvmx_npei_pkt_data_out_ns_s cn56xxp1; }; union cvmx_npei_pkt_data_out_ror { @@ -2078,6 +2115,7 @@ union cvmx_npei_pkt_data_out_ror { } s; struct cvmx_npei_pkt_data_out_ror_s cn52xx; struct cvmx_npei_pkt_data_out_ror_s cn56xx; + struct cvmx_npei_pkt_data_out_ror_s cn56xxp1; }; union cvmx_npei_pkt_dpaddr { @@ -2088,6 +2126,7 @@ union cvmx_npei_pkt_dpaddr { } s; struct cvmx_npei_pkt_dpaddr_s cn52xx; struct cvmx_npei_pkt_dpaddr_s cn56xx; + struct cvmx_npei_pkt_dpaddr_s cn56xxp1; }; union cvmx_npei_pkt_in_bp { @@ -2096,7 +2135,6 @@ union cvmx_npei_pkt_in_bp { uint64_t reserved_32_63:32; uint64_t bp:32; } s; - struct cvmx_npei_pkt_in_bp_s cn52xx; struct cvmx_npei_pkt_in_bp_s cn56xx; }; @@ -2108,6 +2146,7 @@ union cvmx_npei_pkt_in_donex_cnts { } s; struct cvmx_npei_pkt_in_donex_cnts_s cn52xx; struct cvmx_npei_pkt_in_donex_cnts_s cn56xx; + struct cvmx_npei_pkt_in_donex_cnts_s cn56xxp1; }; union cvmx_npei_pkt_in_instr_counts { @@ -2145,6 +2184,7 @@ union cvmx_npei_pkt_input_control { } s; struct cvmx_npei_pkt_input_control_s cn52xx; struct cvmx_npei_pkt_input_control_s cn56xx; + struct cvmx_npei_pkt_input_control_s cn56xxp1; }; union cvmx_npei_pkt_instr_enb { @@ -2155,6 +2195,7 @@ union cvmx_npei_pkt_instr_enb { } s; struct cvmx_npei_pkt_instr_enb_s cn52xx; struct cvmx_npei_pkt_instr_enb_s cn56xx; + struct cvmx_npei_pkt_instr_enb_s cn56xxp1; }; union cvmx_npei_pkt_instr_rd_size { @@ -2174,6 +2215,7 @@ union cvmx_npei_pkt_instr_size { } s; struct cvmx_npei_pkt_instr_size_s cn52xx; struct cvmx_npei_pkt_instr_size_s cn56xx; + struct cvmx_npei_pkt_instr_size_s cn56xxp1; }; union cvmx_npei_pkt_int_levels { @@ -2185,6 +2227,7 @@ union cvmx_npei_pkt_int_levels { } s; struct cvmx_npei_pkt_int_levels_s cn52xx; struct cvmx_npei_pkt_int_levels_s cn56xx; + struct cvmx_npei_pkt_int_levels_s cn56xxp1; }; union cvmx_npei_pkt_iptr { @@ -2195,6 +2238,7 @@ union cvmx_npei_pkt_iptr { } s; struct cvmx_npei_pkt_iptr_s cn52xx; struct cvmx_npei_pkt_iptr_s cn56xx; + struct cvmx_npei_pkt_iptr_s cn56xxp1; }; union cvmx_npei_pkt_out_bmode { @@ -2205,6 +2249,7 @@ union cvmx_npei_pkt_out_bmode { } s; struct cvmx_npei_pkt_out_bmode_s cn52xx; struct cvmx_npei_pkt_out_bmode_s cn56xx; + struct cvmx_npei_pkt_out_bmode_s cn56xxp1; }; union cvmx_npei_pkt_out_enb { @@ -2215,6 +2260,7 @@ union cvmx_npei_pkt_out_enb { } s; struct cvmx_npei_pkt_out_enb_s cn52xx; struct cvmx_npei_pkt_out_enb_s cn56xx; + struct cvmx_npei_pkt_out_enb_s cn56xxp1; }; union cvmx_npei_pkt_output_wmark { @@ -2234,6 +2280,7 @@ union cvmx_npei_pkt_pcie_port { } s; struct cvmx_npei_pkt_pcie_port_s cn52xx; struct cvmx_npei_pkt_pcie_port_s cn56xx; + struct cvmx_npei_pkt_pcie_port_s cn56xxp1; }; union cvmx_npei_pkt_port_in_rst { @@ -2253,6 +2300,7 @@ union cvmx_npei_pkt_slist_es { } s; struct cvmx_npei_pkt_slist_es_s cn52xx; struct cvmx_npei_pkt_slist_es_s cn56xx; + struct cvmx_npei_pkt_slist_es_s cn56xxp1; }; union cvmx_npei_pkt_slist_id_size { @@ -2264,6 +2312,7 @@ union cvmx_npei_pkt_slist_id_size { } s; struct cvmx_npei_pkt_slist_id_size_s cn52xx; struct cvmx_npei_pkt_slist_id_size_s cn56xx; + struct cvmx_npei_pkt_slist_id_size_s cn56xxp1; }; union cvmx_npei_pkt_slist_ns { @@ -2274,6 +2323,7 @@ union cvmx_npei_pkt_slist_ns { } s; struct cvmx_npei_pkt_slist_ns_s cn52xx; struct cvmx_npei_pkt_slist_ns_s cn56xx; + struct cvmx_npei_pkt_slist_ns_s cn56xxp1; }; union cvmx_npei_pkt_slist_ror { @@ -2284,6 +2334,7 @@ union cvmx_npei_pkt_slist_ror { } s; struct cvmx_npei_pkt_slist_ror_s cn52xx; struct cvmx_npei_pkt_slist_ror_s cn56xx; + struct cvmx_npei_pkt_slist_ror_s cn56xxp1; }; union cvmx_npei_pkt_time_int { @@ -2294,6 +2345,7 @@ union cvmx_npei_pkt_time_int { } s; struct cvmx_npei_pkt_time_int_s cn52xx; struct cvmx_npei_pkt_time_int_s cn56xx; + struct cvmx_npei_pkt_time_int_s cn56xxp1; }; union cvmx_npei_pkt_time_int_enb { @@ -2304,6 +2356,7 @@ union cvmx_npei_pkt_time_int_enb { } s; struct cvmx_npei_pkt_time_int_enb_s cn52xx; struct cvmx_npei_pkt_time_int_enb_s cn56xx; + struct cvmx_npei_pkt_time_int_enb_s cn56xxp1; }; union cvmx_npei_rsl_int_blocks { @@ -2318,8 +2371,7 @@ union cvmx_npei_rsl_int_blocks { uint64_t asxpcs0:1; uint64_t reserved_21_21:1; uint64_t pip:1; - uint64_t spx1:1; - uint64_t spx0:1; + uint64_t reserved_18_19:2; uint64_t lmc0:1; uint64_t l2c:1; uint64_t usb1:1; @@ -2331,7 +2383,7 @@ union cvmx_npei_rsl_int_blocks { uint64_t ipd:1; uint64_t reserved_8_8:1; uint64_t zip:1; - uint64_t dfa:1; + uint64_t reserved_6_6:1; uint64_t fpa:1; uint64_t key:1; uint64_t npei:1; @@ -2341,8 +2393,37 @@ union cvmx_npei_rsl_int_blocks { } s; struct cvmx_npei_rsl_int_blocks_s cn52xx; struct cvmx_npei_rsl_int_blocks_s cn52xxp1; - struct cvmx_npei_rsl_int_blocks_s cn56xx; - struct cvmx_npei_rsl_int_blocks_s cn56xxp1; + struct cvmx_npei_rsl_int_blocks_cn56xx { + uint64_t reserved_31_63:33; + uint64_t iob:1; + uint64_t lmc1:1; + uint64_t agl:1; + uint64_t reserved_24_27:4; + uint64_t asxpcs1:1; + uint64_t asxpcs0:1; + uint64_t reserved_21_21:1; + uint64_t pip:1; + uint64_t reserved_18_19:2; + uint64_t lmc0:1; + uint64_t l2c:1; + uint64_t reserved_15_15:1; + uint64_t rad:1; + uint64_t usb:1; + uint64_t pow:1; + uint64_t tim:1; + uint64_t pko:1; + uint64_t ipd:1; + uint64_t reserved_8_8:1; + uint64_t zip:1; + uint64_t reserved_6_6:1; + uint64_t fpa:1; + uint64_t key:1; + uint64_t npei:1; + uint64_t gmx1:1; + uint64_t gmx0:1; + uint64_t mio:1; + } cn56xx; + struct cvmx_npei_rsl_int_blocks_cn56xx cn56xxp1; }; union cvmx_npei_scratch_1 { diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-npi-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-npi-defs.h index f089c780060f..4e03cd8561e3 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-npi-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-npi-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,126 +28,246 @@ #ifndef __CVMX_NPI_DEFS_H__ #define __CVMX_NPI_DEFS_H__ -#define CVMX_NPI_BASE_ADDR_INPUT0 CVMX_NPI_BASE_ADDR_INPUTX(0) -#define CVMX_NPI_BASE_ADDR_INPUT1 CVMX_NPI_BASE_ADDR_INPUTX(1) -#define CVMX_NPI_BASE_ADDR_INPUT2 CVMX_NPI_BASE_ADDR_INPUTX(2) -#define CVMX_NPI_BASE_ADDR_INPUT3 CVMX_NPI_BASE_ADDR_INPUTX(3) -#define CVMX_NPI_BASE_ADDR_INPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000000070ull) + ((offset) & 3) * 16) -#define CVMX_NPI_BASE_ADDR_OUTPUT0 CVMX_NPI_BASE_ADDR_OUTPUTX(0) -#define CVMX_NPI_BASE_ADDR_OUTPUT1 CVMX_NPI_BASE_ADDR_OUTPUTX(1) -#define CVMX_NPI_BASE_ADDR_OUTPUT2 CVMX_NPI_BASE_ADDR_OUTPUTX(2) -#define CVMX_NPI_BASE_ADDR_OUTPUT3 CVMX_NPI_BASE_ADDR_OUTPUTX(3) -#define CVMX_NPI_BASE_ADDR_OUTPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F00000000B8ull) + ((offset) & 3) * 8) -#define CVMX_NPI_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011F00000003F8ull)) -#define CVMX_NPI_BUFF_SIZE_OUTPUT0 CVMX_NPI_BUFF_SIZE_OUTPUTX(0) -#define CVMX_NPI_BUFF_SIZE_OUTPUT1 CVMX_NPI_BUFF_SIZE_OUTPUTX(1) -#define CVMX_NPI_BUFF_SIZE_OUTPUT2 CVMX_NPI_BUFF_SIZE_OUTPUTX(2) -#define CVMX_NPI_BUFF_SIZE_OUTPUT3 CVMX_NPI_BUFF_SIZE_OUTPUTX(3) -#define CVMX_NPI_BUFF_SIZE_OUTPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F00000000E0ull) + ((offset) & 3) * 8) -#define CVMX_NPI_COMP_CTL (CVMX_ADD_IO_SEG(0x00011F0000000218ull)) -#define CVMX_NPI_CTL_STATUS (CVMX_ADD_IO_SEG(0x00011F0000000010ull)) -#define CVMX_NPI_DBG_SELECT (CVMX_ADD_IO_SEG(0x00011F0000000008ull)) -#define CVMX_NPI_DMA_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000000128ull)) -#define CVMX_NPI_DMA_HIGHP_COUNTS (CVMX_ADD_IO_SEG(0x00011F0000000148ull)) -#define CVMX_NPI_DMA_HIGHP_NADDR (CVMX_ADD_IO_SEG(0x00011F0000000158ull)) -#define CVMX_NPI_DMA_LOWP_COUNTS (CVMX_ADD_IO_SEG(0x00011F0000000140ull)) -#define CVMX_NPI_DMA_LOWP_NADDR (CVMX_ADD_IO_SEG(0x00011F0000000150ull)) -#define CVMX_NPI_HIGHP_DBELL (CVMX_ADD_IO_SEG(0x00011F0000000120ull)) -#define CVMX_NPI_HIGHP_IBUFF_SADDR (CVMX_ADD_IO_SEG(0x00011F0000000110ull)) -#define CVMX_NPI_INPUT_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000000138ull)) -#define CVMX_NPI_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000000020ull)) -#define CVMX_NPI_INT_SUM (CVMX_ADD_IO_SEG(0x00011F0000000018ull)) -#define CVMX_NPI_LOWP_DBELL (CVMX_ADD_IO_SEG(0x00011F0000000118ull)) -#define CVMX_NPI_LOWP_IBUFF_SADDR (CVMX_ADD_IO_SEG(0x00011F0000000108ull)) -#define CVMX_NPI_MEM_ACCESS_SUBID3 CVMX_NPI_MEM_ACCESS_SUBIDX(3) -#define CVMX_NPI_MEM_ACCESS_SUBID4 CVMX_NPI_MEM_ACCESS_SUBIDX(4) -#define CVMX_NPI_MEM_ACCESS_SUBID5 CVMX_NPI_MEM_ACCESS_SUBIDX(5) -#define CVMX_NPI_MEM_ACCESS_SUBID6 CVMX_NPI_MEM_ACCESS_SUBIDX(6) -#define CVMX_NPI_MEM_ACCESS_SUBIDX(offset) (CVMX_ADD_IO_SEG(0x00011F0000000028ull) + ((offset) & 7) * 8 - 8*3) -#define CVMX_NPI_MSI_RCV (0x0000000000000190ull) -#define CVMX_NPI_NPI_MSI_RCV (CVMX_ADD_IO_SEG(0x00011F0000001190ull)) -#define CVMX_NPI_NUM_DESC_OUTPUT0 CVMX_NPI_NUM_DESC_OUTPUTX(0) -#define CVMX_NPI_NUM_DESC_OUTPUT1 CVMX_NPI_NUM_DESC_OUTPUTX(1) -#define CVMX_NPI_NUM_DESC_OUTPUT2 CVMX_NPI_NUM_DESC_OUTPUTX(2) -#define CVMX_NPI_NUM_DESC_OUTPUT3 CVMX_NPI_NUM_DESC_OUTPUTX(3) -#define CVMX_NPI_NUM_DESC_OUTPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000000050ull) + ((offset) & 3) * 8) -#define CVMX_NPI_OUTPUT_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000000100ull)) -#define CVMX_NPI_P0_DBPAIR_ADDR CVMX_NPI_PX_DBPAIR_ADDR(0) -#define CVMX_NPI_P0_INSTR_ADDR CVMX_NPI_PX_INSTR_ADDR(0) -#define CVMX_NPI_P0_INSTR_CNTS CVMX_NPI_PX_INSTR_CNTS(0) -#define CVMX_NPI_P0_PAIR_CNTS CVMX_NPI_PX_PAIR_CNTS(0) -#define CVMX_NPI_P1_DBPAIR_ADDR CVMX_NPI_PX_DBPAIR_ADDR(1) -#define CVMX_NPI_P1_INSTR_ADDR CVMX_NPI_PX_INSTR_ADDR(1) -#define CVMX_NPI_P1_INSTR_CNTS CVMX_NPI_PX_INSTR_CNTS(1) -#define CVMX_NPI_P1_PAIR_CNTS CVMX_NPI_PX_PAIR_CNTS(1) -#define CVMX_NPI_P2_DBPAIR_ADDR CVMX_NPI_PX_DBPAIR_ADDR(2) -#define CVMX_NPI_P2_INSTR_ADDR CVMX_NPI_PX_INSTR_ADDR(2) -#define CVMX_NPI_P2_INSTR_CNTS CVMX_NPI_PX_INSTR_CNTS(2) -#define CVMX_NPI_P2_PAIR_CNTS CVMX_NPI_PX_PAIR_CNTS(2) -#define CVMX_NPI_P3_DBPAIR_ADDR CVMX_NPI_PX_DBPAIR_ADDR(3) -#define CVMX_NPI_P3_INSTR_ADDR CVMX_NPI_PX_INSTR_ADDR(3) -#define CVMX_NPI_P3_INSTR_CNTS CVMX_NPI_PX_INSTR_CNTS(3) -#define CVMX_NPI_P3_PAIR_CNTS CVMX_NPI_PX_PAIR_CNTS(3) -#define CVMX_NPI_PCI_BAR1_INDEXX(offset) (CVMX_ADD_IO_SEG(0x00011F0000001100ull) + ((offset) & 31) * 4) -#define CVMX_NPI_PCI_BIST_REG (CVMX_ADD_IO_SEG(0x00011F00000011C0ull)) -#define CVMX_NPI_PCI_BURST_SIZE (CVMX_ADD_IO_SEG(0x00011F00000000D8ull)) -#define CVMX_NPI_PCI_CFG00 (CVMX_ADD_IO_SEG(0x00011F0000001800ull)) -#define CVMX_NPI_PCI_CFG01 (CVMX_ADD_IO_SEG(0x00011F0000001804ull)) -#define CVMX_NPI_PCI_CFG02 (CVMX_ADD_IO_SEG(0x00011F0000001808ull)) -#define CVMX_NPI_PCI_CFG03 (CVMX_ADD_IO_SEG(0x00011F000000180Cull)) -#define CVMX_NPI_PCI_CFG04 (CVMX_ADD_IO_SEG(0x00011F0000001810ull)) -#define CVMX_NPI_PCI_CFG05 (CVMX_ADD_IO_SEG(0x00011F0000001814ull)) -#define CVMX_NPI_PCI_CFG06 (CVMX_ADD_IO_SEG(0x00011F0000001818ull)) -#define CVMX_NPI_PCI_CFG07 (CVMX_ADD_IO_SEG(0x00011F000000181Cull)) -#define CVMX_NPI_PCI_CFG08 (CVMX_ADD_IO_SEG(0x00011F0000001820ull)) -#define CVMX_NPI_PCI_CFG09 (CVMX_ADD_IO_SEG(0x00011F0000001824ull)) -#define CVMX_NPI_PCI_CFG10 (CVMX_ADD_IO_SEG(0x00011F0000001828ull)) -#define CVMX_NPI_PCI_CFG11 (CVMX_ADD_IO_SEG(0x00011F000000182Cull)) -#define CVMX_NPI_PCI_CFG12 (CVMX_ADD_IO_SEG(0x00011F0000001830ull)) -#define CVMX_NPI_PCI_CFG13 (CVMX_ADD_IO_SEG(0x00011F0000001834ull)) -#define CVMX_NPI_PCI_CFG15 (CVMX_ADD_IO_SEG(0x00011F000000183Cull)) -#define CVMX_NPI_PCI_CFG16 (CVMX_ADD_IO_SEG(0x00011F0000001840ull)) -#define CVMX_NPI_PCI_CFG17 (CVMX_ADD_IO_SEG(0x00011F0000001844ull)) -#define CVMX_NPI_PCI_CFG18 (CVMX_ADD_IO_SEG(0x00011F0000001848ull)) -#define CVMX_NPI_PCI_CFG19 (CVMX_ADD_IO_SEG(0x00011F000000184Cull)) -#define CVMX_NPI_PCI_CFG20 (CVMX_ADD_IO_SEG(0x00011F0000001850ull)) -#define CVMX_NPI_PCI_CFG21 (CVMX_ADD_IO_SEG(0x00011F0000001854ull)) -#define CVMX_NPI_PCI_CFG22 (CVMX_ADD_IO_SEG(0x00011F0000001858ull)) -#define CVMX_NPI_PCI_CFG56 (CVMX_ADD_IO_SEG(0x00011F00000018E0ull)) -#define CVMX_NPI_PCI_CFG57 (CVMX_ADD_IO_SEG(0x00011F00000018E4ull)) -#define CVMX_NPI_PCI_CFG58 (CVMX_ADD_IO_SEG(0x00011F00000018E8ull)) -#define CVMX_NPI_PCI_CFG59 (CVMX_ADD_IO_SEG(0x00011F00000018ECull)) -#define CVMX_NPI_PCI_CFG60 (CVMX_ADD_IO_SEG(0x00011F00000018F0ull)) -#define CVMX_NPI_PCI_CFG61 (CVMX_ADD_IO_SEG(0x00011F00000018F4ull)) -#define CVMX_NPI_PCI_CFG62 (CVMX_ADD_IO_SEG(0x00011F00000018F8ull)) -#define CVMX_NPI_PCI_CFG63 (CVMX_ADD_IO_SEG(0x00011F00000018FCull)) -#define CVMX_NPI_PCI_CNT_REG (CVMX_ADD_IO_SEG(0x00011F00000011B8ull)) -#define CVMX_NPI_PCI_CTL_STATUS_2 (CVMX_ADD_IO_SEG(0x00011F000000118Cull)) -#define CVMX_NPI_PCI_INT_ARB_CFG (CVMX_ADD_IO_SEG(0x00011F0000000130ull)) -#define CVMX_NPI_PCI_INT_ENB2 (CVMX_ADD_IO_SEG(0x00011F00000011A0ull)) -#define CVMX_NPI_PCI_INT_SUM2 (CVMX_ADD_IO_SEG(0x00011F0000001198ull)) -#define CVMX_NPI_PCI_READ_CMD (CVMX_ADD_IO_SEG(0x00011F0000000048ull)) -#define CVMX_NPI_PCI_READ_CMD_6 (CVMX_ADD_IO_SEG(0x00011F0000001180ull)) -#define CVMX_NPI_PCI_READ_CMD_C (CVMX_ADD_IO_SEG(0x00011F0000001184ull)) -#define CVMX_NPI_PCI_READ_CMD_E (CVMX_ADD_IO_SEG(0x00011F0000001188ull)) -#define CVMX_NPI_PCI_SCM_REG (CVMX_ADD_IO_SEG(0x00011F00000011A8ull)) -#define CVMX_NPI_PCI_TSR_REG (CVMX_ADD_IO_SEG(0x00011F00000011B0ull)) -#define CVMX_NPI_PORT32_INSTR_HDR (CVMX_ADD_IO_SEG(0x00011F00000001F8ull)) -#define CVMX_NPI_PORT33_INSTR_HDR (CVMX_ADD_IO_SEG(0x00011F0000000200ull)) -#define CVMX_NPI_PORT34_INSTR_HDR (CVMX_ADD_IO_SEG(0x00011F0000000208ull)) -#define CVMX_NPI_PORT35_INSTR_HDR (CVMX_ADD_IO_SEG(0x00011F0000000210ull)) -#define CVMX_NPI_PORT_BP_CONTROL (CVMX_ADD_IO_SEG(0x00011F00000001F0ull)) -#define CVMX_NPI_PX_DBPAIR_ADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000000180ull) + ((offset) & 3) * 8) -#define CVMX_NPI_PX_INSTR_ADDR(offset) (CVMX_ADD_IO_SEG(0x00011F00000001C0ull) + ((offset) & 3) * 8) -#define CVMX_NPI_PX_INSTR_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F00000001A0ull) + ((offset) & 3) * 8) -#define CVMX_NPI_PX_PAIR_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F0000000160ull) + ((offset) & 3) * 8) -#define CVMX_NPI_RSL_INT_BLOCKS (CVMX_ADD_IO_SEG(0x00011F0000000000ull)) -#define CVMX_NPI_SIZE_INPUT0 CVMX_NPI_SIZE_INPUTX(0) -#define CVMX_NPI_SIZE_INPUT1 CVMX_NPI_SIZE_INPUTX(1) -#define CVMX_NPI_SIZE_INPUT2 CVMX_NPI_SIZE_INPUTX(2) -#define CVMX_NPI_SIZE_INPUT3 CVMX_NPI_SIZE_INPUTX(3) -#define CVMX_NPI_SIZE_INPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000000078ull) + ((offset) & 3) * 16) -#define CVMX_NPI_WIN_READ_TO (CVMX_ADD_IO_SEG(0x00011F00000001E0ull)) +#define CVMX_NPI_BASE_ADDR_INPUT0 \ + CVMX_ADD_IO_SEG(0x00011F0000000070ull) +#define CVMX_NPI_BASE_ADDR_INPUT1 \ + CVMX_ADD_IO_SEG(0x00011F0000000080ull) +#define CVMX_NPI_BASE_ADDR_INPUT2 \ + CVMX_ADD_IO_SEG(0x00011F0000000090ull) +#define CVMX_NPI_BASE_ADDR_INPUT3 \ + CVMX_ADD_IO_SEG(0x00011F00000000A0ull) +#define CVMX_NPI_BASE_ADDR_INPUTX(offset) \ + CVMX_ADD_IO_SEG(0x00011F0000000070ull + (((offset) & 3) * 16)) +#define CVMX_NPI_BASE_ADDR_OUTPUT0 \ + CVMX_ADD_IO_SEG(0x00011F00000000B8ull) +#define CVMX_NPI_BASE_ADDR_OUTPUT1 \ + CVMX_ADD_IO_SEG(0x00011F00000000C0ull) +#define CVMX_NPI_BASE_ADDR_OUTPUT2 \ + CVMX_ADD_IO_SEG(0x00011F00000000C8ull) +#define CVMX_NPI_BASE_ADDR_OUTPUT3 \ + CVMX_ADD_IO_SEG(0x00011F00000000D0ull) +#define CVMX_NPI_BASE_ADDR_OUTPUTX(offset) \ + CVMX_ADD_IO_SEG(0x00011F00000000B8ull + (((offset) & 3) * 8)) +#define CVMX_NPI_BIST_STATUS \ + CVMX_ADD_IO_SEG(0x00011F00000003F8ull) +#define CVMX_NPI_BUFF_SIZE_OUTPUT0 \ + CVMX_ADD_IO_SEG(0x00011F00000000E0ull) +#define CVMX_NPI_BUFF_SIZE_OUTPUT1 \ + CVMX_ADD_IO_SEG(0x00011F00000000E8ull) +#define CVMX_NPI_BUFF_SIZE_OUTPUT2 \ + CVMX_ADD_IO_SEG(0x00011F00000000F0ull) +#define CVMX_NPI_BUFF_SIZE_OUTPUT3 \ + CVMX_ADD_IO_SEG(0x00011F00000000F8ull) +#define CVMX_NPI_BUFF_SIZE_OUTPUTX(offset) \ + CVMX_ADD_IO_SEG(0x00011F00000000E0ull + (((offset) & 3) * 8)) +#define CVMX_NPI_COMP_CTL \ + CVMX_ADD_IO_SEG(0x00011F0000000218ull) +#define CVMX_NPI_CTL_STATUS \ + CVMX_ADD_IO_SEG(0x00011F0000000010ull) +#define CVMX_NPI_DBG_SELECT \ + CVMX_ADD_IO_SEG(0x00011F0000000008ull) +#define CVMX_NPI_DMA_CONTROL \ + CVMX_ADD_IO_SEG(0x00011F0000000128ull) +#define CVMX_NPI_DMA_HIGHP_COUNTS \ + CVMX_ADD_IO_SEG(0x00011F0000000148ull) +#define CVMX_NPI_DMA_HIGHP_NADDR \ + CVMX_ADD_IO_SEG(0x00011F0000000158ull) +#define CVMX_NPI_DMA_LOWP_COUNTS \ + CVMX_ADD_IO_SEG(0x00011F0000000140ull) +#define CVMX_NPI_DMA_LOWP_NADDR \ + CVMX_ADD_IO_SEG(0x00011F0000000150ull) +#define CVMX_NPI_HIGHP_DBELL \ + CVMX_ADD_IO_SEG(0x00011F0000000120ull) +#define CVMX_NPI_HIGHP_IBUFF_SADDR \ + CVMX_ADD_IO_SEG(0x00011F0000000110ull) +#define CVMX_NPI_INPUT_CONTROL \ + CVMX_ADD_IO_SEG(0x00011F0000000138ull) +#define CVMX_NPI_INT_ENB \ + CVMX_ADD_IO_SEG(0x00011F0000000020ull) +#define CVMX_NPI_INT_SUM \ + CVMX_ADD_IO_SEG(0x00011F0000000018ull) +#define CVMX_NPI_LOWP_DBELL \ + CVMX_ADD_IO_SEG(0x00011F0000000118ull) +#define CVMX_NPI_LOWP_IBUFF_SADDR \ + CVMX_ADD_IO_SEG(0x00011F0000000108ull) +#define CVMX_NPI_MEM_ACCESS_SUBID3 \ + CVMX_ADD_IO_SEG(0x00011F0000000028ull) +#define CVMX_NPI_MEM_ACCESS_SUBID4 \ + CVMX_ADD_IO_SEG(0x00011F0000000030ull) +#define CVMX_NPI_MEM_ACCESS_SUBID5 \ + CVMX_ADD_IO_SEG(0x00011F0000000038ull) +#define CVMX_NPI_MEM_ACCESS_SUBID6 \ + CVMX_ADD_IO_SEG(0x00011F0000000040ull) +#define CVMX_NPI_MEM_ACCESS_SUBIDX(offset) \ + CVMX_ADD_IO_SEG(0x00011F0000000028ull + (((offset) & 7) * 8) - 8 * 3) +#define CVMX_NPI_MSI_RCV \ + (0x0000000000000190ull) +#define CVMX_NPI_NPI_MSI_RCV \ + CVMX_ADD_IO_SEG(0x00011F0000001190ull) +#define CVMX_NPI_NUM_DESC_OUTPUT0 \ + CVMX_ADD_IO_SEG(0x00011F0000000050ull) +#define CVMX_NPI_NUM_DESC_OUTPUT1 \ + CVMX_ADD_IO_SEG(0x00011F0000000058ull) +#define CVMX_NPI_NUM_DESC_OUTPUT2 \ + CVMX_ADD_IO_SEG(0x00011F0000000060ull) +#define CVMX_NPI_NUM_DESC_OUTPUT3 \ + CVMX_ADD_IO_SEG(0x00011F0000000068ull) +#define CVMX_NPI_NUM_DESC_OUTPUTX(offset) \ + CVMX_ADD_IO_SEG(0x00011F0000000050ull + (((offset) & 3) * 8)) +#define CVMX_NPI_OUTPUT_CONTROL \ + CVMX_ADD_IO_SEG(0x00011F0000000100ull) +#define CVMX_NPI_P0_DBPAIR_ADDR \ + CVMX_ADD_IO_SEG(0x00011F0000000180ull) +#define CVMX_NPI_P0_INSTR_ADDR \ + CVMX_ADD_IO_SEG(0x00011F00000001C0ull) +#define CVMX_NPI_P0_INSTR_CNTS \ + CVMX_ADD_IO_SEG(0x00011F00000001A0ull) +#define CVMX_NPI_P0_PAIR_CNTS \ + CVMX_ADD_IO_SEG(0x00011F0000000160ull) +#define CVMX_NPI_P1_DBPAIR_ADDR \ + CVMX_ADD_IO_SEG(0x00011F0000000188ull) +#define CVMX_NPI_P1_INSTR_ADDR \ + CVMX_ADD_IO_SEG(0x00011F00000001C8ull) +#define CVMX_NPI_P1_INSTR_CNTS \ + CVMX_ADD_IO_SEG(0x00011F00000001A8ull) +#define CVMX_NPI_P1_PAIR_CNTS \ + CVMX_ADD_IO_SEG(0x00011F0000000168ull) +#define CVMX_NPI_P2_DBPAIR_ADDR \ + CVMX_ADD_IO_SEG(0x00011F0000000190ull) +#define CVMX_NPI_P2_INSTR_ADDR \ + CVMX_ADD_IO_SEG(0x00011F00000001D0ull) +#define CVMX_NPI_P2_INSTR_CNTS \ + CVMX_ADD_IO_SEG(0x00011F00000001B0ull) +#define CVMX_NPI_P2_PAIR_CNTS \ + CVMX_ADD_IO_SEG(0x00011F0000000170ull) +#define CVMX_NPI_P3_DBPAIR_ADDR \ + CVMX_ADD_IO_SEG(0x00011F0000000198ull) +#define CVMX_NPI_P3_INSTR_ADDR \ + CVMX_ADD_IO_SEG(0x00011F00000001D8ull) +#define CVMX_NPI_P3_INSTR_CNTS \ + CVMX_ADD_IO_SEG(0x00011F00000001B8ull) +#define CVMX_NPI_P3_PAIR_CNTS \ + CVMX_ADD_IO_SEG(0x00011F0000000178ull) +#define CVMX_NPI_PCI_BAR1_INDEXX(offset) \ + CVMX_ADD_IO_SEG(0x00011F0000001100ull + (((offset) & 31) * 4)) +#define CVMX_NPI_PCI_BIST_REG \ + CVMX_ADD_IO_SEG(0x00011F00000011C0ull) +#define CVMX_NPI_PCI_BURST_SIZE \ + CVMX_ADD_IO_SEG(0x00011F00000000D8ull) +#define CVMX_NPI_PCI_CFG00 \ + CVMX_ADD_IO_SEG(0x00011F0000001800ull) +#define CVMX_NPI_PCI_CFG01 \ + CVMX_ADD_IO_SEG(0x00011F0000001804ull) +#define CVMX_NPI_PCI_CFG02 \ + CVMX_ADD_IO_SEG(0x00011F0000001808ull) +#define CVMX_NPI_PCI_CFG03 \ + CVMX_ADD_IO_SEG(0x00011F000000180Cull) +#define CVMX_NPI_PCI_CFG04 \ + CVMX_ADD_IO_SEG(0x00011F0000001810ull) +#define CVMX_NPI_PCI_CFG05 \ + CVMX_ADD_IO_SEG(0x00011F0000001814ull) +#define CVMX_NPI_PCI_CFG06 \ + CVMX_ADD_IO_SEG(0x00011F0000001818ull) +#define CVMX_NPI_PCI_CFG07 \ + CVMX_ADD_IO_SEG(0x00011F000000181Cull) +#define CVMX_NPI_PCI_CFG08 \ + CVMX_ADD_IO_SEG(0x00011F0000001820ull) +#define CVMX_NPI_PCI_CFG09 \ + CVMX_ADD_IO_SEG(0x00011F0000001824ull) +#define CVMX_NPI_PCI_CFG10 \ + CVMX_ADD_IO_SEG(0x00011F0000001828ull) +#define CVMX_NPI_PCI_CFG11 \ + CVMX_ADD_IO_SEG(0x00011F000000182Cull) +#define CVMX_NPI_PCI_CFG12 \ + CVMX_ADD_IO_SEG(0x00011F0000001830ull) +#define CVMX_NPI_PCI_CFG13 \ + CVMX_ADD_IO_SEG(0x00011F0000001834ull) +#define CVMX_NPI_PCI_CFG15 \ + CVMX_ADD_IO_SEG(0x00011F000000183Cull) +#define CVMX_NPI_PCI_CFG16 \ + CVMX_ADD_IO_SEG(0x00011F0000001840ull) +#define CVMX_NPI_PCI_CFG17 \ + CVMX_ADD_IO_SEG(0x00011F0000001844ull) +#define CVMX_NPI_PCI_CFG18 \ + CVMX_ADD_IO_SEG(0x00011F0000001848ull) +#define CVMX_NPI_PCI_CFG19 \ + CVMX_ADD_IO_SEG(0x00011F000000184Cull) +#define CVMX_NPI_PCI_CFG20 \ + CVMX_ADD_IO_SEG(0x00011F0000001850ull) +#define CVMX_NPI_PCI_CFG21 \ + CVMX_ADD_IO_SEG(0x00011F0000001854ull) +#define CVMX_NPI_PCI_CFG22 \ + CVMX_ADD_IO_SEG(0x00011F0000001858ull) +#define CVMX_NPI_PCI_CFG56 \ + CVMX_ADD_IO_SEG(0x00011F00000018E0ull) +#define CVMX_NPI_PCI_CFG57 \ + CVMX_ADD_IO_SEG(0x00011F00000018E4ull) +#define CVMX_NPI_PCI_CFG58 \ + CVMX_ADD_IO_SEG(0x00011F00000018E8ull) +#define CVMX_NPI_PCI_CFG59 \ + CVMX_ADD_IO_SEG(0x00011F00000018ECull) +#define CVMX_NPI_PCI_CFG60 \ + CVMX_ADD_IO_SEG(0x00011F00000018F0ull) +#define CVMX_NPI_PCI_CFG61 \ + CVMX_ADD_IO_SEG(0x00011F00000018F4ull) +#define CVMX_NPI_PCI_CFG62 \ + CVMX_ADD_IO_SEG(0x00011F00000018F8ull) +#define CVMX_NPI_PCI_CFG63 \ + CVMX_ADD_IO_SEG(0x00011F00000018FCull) +#define CVMX_NPI_PCI_CNT_REG \ + CVMX_ADD_IO_SEG(0x00011F00000011B8ull) +#define CVMX_NPI_PCI_CTL_STATUS_2 \ + CVMX_ADD_IO_SEG(0x00011F000000118Cull) +#define CVMX_NPI_PCI_INT_ARB_CFG \ + CVMX_ADD_IO_SEG(0x00011F0000000130ull) +#define CVMX_NPI_PCI_INT_ENB2 \ + CVMX_ADD_IO_SEG(0x00011F00000011A0ull) +#define CVMX_NPI_PCI_INT_SUM2 \ + CVMX_ADD_IO_SEG(0x00011F0000001198ull) +#define CVMX_NPI_PCI_READ_CMD \ + CVMX_ADD_IO_SEG(0x00011F0000000048ull) +#define CVMX_NPI_PCI_READ_CMD_6 \ + CVMX_ADD_IO_SEG(0x00011F0000001180ull) +#define CVMX_NPI_PCI_READ_CMD_C \ + CVMX_ADD_IO_SEG(0x00011F0000001184ull) +#define CVMX_NPI_PCI_READ_CMD_E \ + CVMX_ADD_IO_SEG(0x00011F0000001188ull) +#define CVMX_NPI_PCI_SCM_REG \ + CVMX_ADD_IO_SEG(0x00011F00000011A8ull) +#define CVMX_NPI_PCI_TSR_REG \ + CVMX_ADD_IO_SEG(0x00011F00000011B0ull) +#define CVMX_NPI_PORT32_INSTR_HDR \ + CVMX_ADD_IO_SEG(0x00011F00000001F8ull) +#define CVMX_NPI_PORT33_INSTR_HDR \ + CVMX_ADD_IO_SEG(0x00011F0000000200ull) +#define CVMX_NPI_PORT34_INSTR_HDR \ + CVMX_ADD_IO_SEG(0x00011F0000000208ull) +#define CVMX_NPI_PORT35_INSTR_HDR \ + CVMX_ADD_IO_SEG(0x00011F0000000210ull) +#define CVMX_NPI_PORT_BP_CONTROL \ + CVMX_ADD_IO_SEG(0x00011F00000001F0ull) +#define CVMX_NPI_PX_DBPAIR_ADDR(offset) \ + CVMX_ADD_IO_SEG(0x00011F0000000180ull + (((offset) & 3) * 8)) +#define CVMX_NPI_PX_INSTR_ADDR(offset) \ + CVMX_ADD_IO_SEG(0x00011F00000001C0ull + (((offset) & 3) * 8)) +#define CVMX_NPI_PX_INSTR_CNTS(offset) \ + CVMX_ADD_IO_SEG(0x00011F00000001A0ull + (((offset) & 3) * 8)) +#define CVMX_NPI_PX_PAIR_CNTS(offset) \ + CVMX_ADD_IO_SEG(0x00011F0000000160ull + (((offset) & 3) * 8)) +#define CVMX_NPI_RSL_INT_BLOCKS \ + CVMX_ADD_IO_SEG(0x00011F0000000000ull) +#define CVMX_NPI_SIZE_INPUT0 \ + CVMX_ADD_IO_SEG(0x00011F0000000078ull) +#define CVMX_NPI_SIZE_INPUT1 \ + CVMX_ADD_IO_SEG(0x00011F0000000088ull) +#define CVMX_NPI_SIZE_INPUT2 \ + CVMX_ADD_IO_SEG(0x00011F0000000098ull) +#define CVMX_NPI_SIZE_INPUT3 \ + CVMX_ADD_IO_SEG(0x00011F00000000A8ull) +#define CVMX_NPI_SIZE_INPUTX(offset) \ + CVMX_ADD_IO_SEG(0x00011F0000000078ull + (((offset) & 3) * 16)) +#define CVMX_NPI_WIN_READ_TO \ + CVMX_ADD_IO_SEG(0x00011F00000001E0ull) union cvmx_npi_base_addr_inputx { uint64_t u64; diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-pci-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-pci-defs.h index 6ff6d9d357ba..90f8d6535753 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-pci-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-pci-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,91 +28,184 @@ #ifndef __CVMX_PCI_DEFS_H__ #define __CVMX_PCI_DEFS_H__ -#define CVMX_PCI_BAR1_INDEXX(offset) (0x0000000000000100ull + ((offset) & 31) * 4) -#define CVMX_PCI_BIST_REG (0x00000000000001C0ull) -#define CVMX_PCI_CFG00 (0x0000000000000000ull) -#define CVMX_PCI_CFG01 (0x0000000000000004ull) -#define CVMX_PCI_CFG02 (0x0000000000000008ull) -#define CVMX_PCI_CFG03 (0x000000000000000Cull) -#define CVMX_PCI_CFG04 (0x0000000000000010ull) -#define CVMX_PCI_CFG05 (0x0000000000000014ull) -#define CVMX_PCI_CFG06 (0x0000000000000018ull) -#define CVMX_PCI_CFG07 (0x000000000000001Cull) -#define CVMX_PCI_CFG08 (0x0000000000000020ull) -#define CVMX_PCI_CFG09 (0x0000000000000024ull) -#define CVMX_PCI_CFG10 (0x0000000000000028ull) -#define CVMX_PCI_CFG11 (0x000000000000002Cull) -#define CVMX_PCI_CFG12 (0x0000000000000030ull) -#define CVMX_PCI_CFG13 (0x0000000000000034ull) -#define CVMX_PCI_CFG15 (0x000000000000003Cull) -#define CVMX_PCI_CFG16 (0x0000000000000040ull) -#define CVMX_PCI_CFG17 (0x0000000000000044ull) -#define CVMX_PCI_CFG18 (0x0000000000000048ull) -#define CVMX_PCI_CFG19 (0x000000000000004Cull) -#define CVMX_PCI_CFG20 (0x0000000000000050ull) -#define CVMX_PCI_CFG21 (0x0000000000000054ull) -#define CVMX_PCI_CFG22 (0x0000000000000058ull) -#define CVMX_PCI_CFG56 (0x00000000000000E0ull) -#define CVMX_PCI_CFG57 (0x00000000000000E4ull) -#define CVMX_PCI_CFG58 (0x00000000000000E8ull) -#define CVMX_PCI_CFG59 (0x00000000000000ECull) -#define CVMX_PCI_CFG60 (0x00000000000000F0ull) -#define CVMX_PCI_CFG61 (0x00000000000000F4ull) -#define CVMX_PCI_CFG62 (0x00000000000000F8ull) -#define CVMX_PCI_CFG63 (0x00000000000000FCull) -#define CVMX_PCI_CNT_REG (0x00000000000001B8ull) -#define CVMX_PCI_CTL_STATUS_2 (0x000000000000018Cull) -#define CVMX_PCI_DBELL_X(offset) (0x0000000000000080ull + ((offset) & 3) * 8) -#define CVMX_PCI_DMA_CNT0 CVMX_PCI_DMA_CNTX(0) -#define CVMX_PCI_DMA_CNT1 CVMX_PCI_DMA_CNTX(1) -#define CVMX_PCI_DMA_CNTX(offset) (0x00000000000000A0ull + ((offset) & 1) * 8) -#define CVMX_PCI_DMA_INT_LEV0 CVMX_PCI_DMA_INT_LEVX(0) -#define CVMX_PCI_DMA_INT_LEV1 CVMX_PCI_DMA_INT_LEVX(1) -#define CVMX_PCI_DMA_INT_LEVX(offset) (0x00000000000000A4ull + ((offset) & 1) * 8) -#define CVMX_PCI_DMA_TIME0 CVMX_PCI_DMA_TIMEX(0) -#define CVMX_PCI_DMA_TIME1 CVMX_PCI_DMA_TIMEX(1) -#define CVMX_PCI_DMA_TIMEX(offset) (0x00000000000000B0ull + ((offset) & 1) * 4) -#define CVMX_PCI_INSTR_COUNT0 CVMX_PCI_INSTR_COUNTX(0) -#define CVMX_PCI_INSTR_COUNT1 CVMX_PCI_INSTR_COUNTX(1) -#define CVMX_PCI_INSTR_COUNT2 CVMX_PCI_INSTR_COUNTX(2) -#define CVMX_PCI_INSTR_COUNT3 CVMX_PCI_INSTR_COUNTX(3) -#define CVMX_PCI_INSTR_COUNTX(offset) (0x0000000000000084ull + ((offset) & 3) * 8) -#define CVMX_PCI_INT_ENB (0x0000000000000038ull) -#define CVMX_PCI_INT_ENB2 (0x00000000000001A0ull) -#define CVMX_PCI_INT_SUM (0x0000000000000030ull) -#define CVMX_PCI_INT_SUM2 (0x0000000000000198ull) -#define CVMX_PCI_MSI_RCV (0x00000000000000F0ull) -#define CVMX_PCI_PKTS_SENT0 CVMX_PCI_PKTS_SENTX(0) -#define CVMX_PCI_PKTS_SENT1 CVMX_PCI_PKTS_SENTX(1) -#define CVMX_PCI_PKTS_SENT2 CVMX_PCI_PKTS_SENTX(2) -#define CVMX_PCI_PKTS_SENT3 CVMX_PCI_PKTS_SENTX(3) -#define CVMX_PCI_PKTS_SENTX(offset) (0x0000000000000040ull + ((offset) & 3) * 16) -#define CVMX_PCI_PKTS_SENT_INT_LEV0 CVMX_PCI_PKTS_SENT_INT_LEVX(0) -#define CVMX_PCI_PKTS_SENT_INT_LEV1 CVMX_PCI_PKTS_SENT_INT_LEVX(1) -#define CVMX_PCI_PKTS_SENT_INT_LEV2 CVMX_PCI_PKTS_SENT_INT_LEVX(2) -#define CVMX_PCI_PKTS_SENT_INT_LEV3 CVMX_PCI_PKTS_SENT_INT_LEVX(3) -#define CVMX_PCI_PKTS_SENT_INT_LEVX(offset) (0x0000000000000048ull + ((offset) & 3) * 16) -#define CVMX_PCI_PKTS_SENT_TIME0 CVMX_PCI_PKTS_SENT_TIMEX(0) -#define CVMX_PCI_PKTS_SENT_TIME1 CVMX_PCI_PKTS_SENT_TIMEX(1) -#define CVMX_PCI_PKTS_SENT_TIME2 CVMX_PCI_PKTS_SENT_TIMEX(2) -#define CVMX_PCI_PKTS_SENT_TIME3 CVMX_PCI_PKTS_SENT_TIMEX(3) -#define CVMX_PCI_PKTS_SENT_TIMEX(offset) (0x000000000000004Cull + ((offset) & 3) * 16) -#define CVMX_PCI_PKT_CREDITS0 CVMX_PCI_PKT_CREDITSX(0) -#define CVMX_PCI_PKT_CREDITS1 CVMX_PCI_PKT_CREDITSX(1) -#define CVMX_PCI_PKT_CREDITS2 CVMX_PCI_PKT_CREDITSX(2) -#define CVMX_PCI_PKT_CREDITS3 CVMX_PCI_PKT_CREDITSX(3) -#define CVMX_PCI_PKT_CREDITSX(offset) (0x0000000000000044ull + ((offset) & 3) * 16) -#define CVMX_PCI_READ_CMD_6 (0x0000000000000180ull) -#define CVMX_PCI_READ_CMD_C (0x0000000000000184ull) -#define CVMX_PCI_READ_CMD_E (0x0000000000000188ull) -#define CVMX_PCI_READ_TIMEOUT (CVMX_ADD_IO_SEG(0x00011F00000000B0ull)) -#define CVMX_PCI_SCM_REG (0x00000000000001A8ull) -#define CVMX_PCI_TSR_REG (0x00000000000001B0ull) -#define CVMX_PCI_WIN_RD_ADDR (0x0000000000000008ull) -#define CVMX_PCI_WIN_RD_DATA (0x0000000000000020ull) -#define CVMX_PCI_WIN_WR_ADDR (0x0000000000000000ull) -#define CVMX_PCI_WIN_WR_DATA (0x0000000000000010ull) -#define CVMX_PCI_WIN_WR_MASK (0x0000000000000018ull) +#define CVMX_PCI_BAR1_INDEXX(offset) \ + (0x0000000000000100ull + (((offset) & 31) * 4)) +#define CVMX_PCI_BIST_REG \ + (0x00000000000001C0ull) +#define CVMX_PCI_CFG00 \ + (0x0000000000000000ull) +#define CVMX_PCI_CFG01 \ + (0x0000000000000004ull) +#define CVMX_PCI_CFG02 \ + (0x0000000000000008ull) +#define CVMX_PCI_CFG03 \ + (0x000000000000000Cull) +#define CVMX_PCI_CFG04 \ + (0x0000000000000010ull) +#define CVMX_PCI_CFG05 \ + (0x0000000000000014ull) +#define CVMX_PCI_CFG06 \ + (0x0000000000000018ull) +#define CVMX_PCI_CFG07 \ + (0x000000000000001Cull) +#define CVMX_PCI_CFG08 \ + (0x0000000000000020ull) +#define CVMX_PCI_CFG09 \ + (0x0000000000000024ull) +#define CVMX_PCI_CFG10 \ + (0x0000000000000028ull) +#define CVMX_PCI_CFG11 \ + (0x000000000000002Cull) +#define CVMX_PCI_CFG12 \ + (0x0000000000000030ull) +#define CVMX_PCI_CFG13 \ + (0x0000000000000034ull) +#define CVMX_PCI_CFG15 \ + (0x000000000000003Cull) +#define CVMX_PCI_CFG16 \ + (0x0000000000000040ull) +#define CVMX_PCI_CFG17 \ + (0x0000000000000044ull) +#define CVMX_PCI_CFG18 \ + (0x0000000000000048ull) +#define CVMX_PCI_CFG19 \ + (0x000000000000004Cull) +#define CVMX_PCI_CFG20 \ + (0x0000000000000050ull) +#define CVMX_PCI_CFG21 \ + (0x0000000000000054ull) +#define CVMX_PCI_CFG22 \ + (0x0000000000000058ull) +#define CVMX_PCI_CFG56 \ + (0x00000000000000E0ull) +#define CVMX_PCI_CFG57 \ + (0x00000000000000E4ull) +#define CVMX_PCI_CFG58 \ + (0x00000000000000E8ull) +#define CVMX_PCI_CFG59 \ + (0x00000000000000ECull) +#define CVMX_PCI_CFG60 \ + (0x00000000000000F0ull) +#define CVMX_PCI_CFG61 \ + (0x00000000000000F4ull) +#define CVMX_PCI_CFG62 \ + (0x00000000000000F8ull) +#define CVMX_PCI_CFG63 \ + (0x00000000000000FCull) +#define CVMX_PCI_CNT_REG \ + (0x00000000000001B8ull) +#define CVMX_PCI_CTL_STATUS_2 \ + (0x000000000000018Cull) +#define CVMX_PCI_DBELL_0 \ + (0x0000000000000080ull) +#define CVMX_PCI_DBELL_1 \ + (0x0000000000000088ull) +#define CVMX_PCI_DBELL_2 \ + (0x0000000000000090ull) +#define CVMX_PCI_DBELL_3 \ + (0x0000000000000098ull) +#define CVMX_PCI_DBELL_X(offset) \ + (0x0000000000000080ull + (((offset) & 3) * 8)) +#define CVMX_PCI_DMA_CNT0 \ + (0x00000000000000A0ull) +#define CVMX_PCI_DMA_CNT1 \ + (0x00000000000000A8ull) +#define CVMX_PCI_DMA_CNTX(offset) \ + (0x00000000000000A0ull + (((offset) & 1) * 8)) +#define CVMX_PCI_DMA_INT_LEV0 \ + (0x00000000000000A4ull) +#define CVMX_PCI_DMA_INT_LEV1 \ + (0x00000000000000ACull) +#define CVMX_PCI_DMA_INT_LEVX(offset) \ + (0x00000000000000A4ull + (((offset) & 1) * 8)) +#define CVMX_PCI_DMA_TIME0 \ + (0x00000000000000B0ull) +#define CVMX_PCI_DMA_TIME1 \ + (0x00000000000000B4ull) +#define CVMX_PCI_DMA_TIMEX(offset) \ + (0x00000000000000B0ull + (((offset) & 1) * 4)) +#define CVMX_PCI_INSTR_COUNT0 \ + (0x0000000000000084ull) +#define CVMX_PCI_INSTR_COUNT1 \ + (0x000000000000008Cull) +#define CVMX_PCI_INSTR_COUNT2 \ + (0x0000000000000094ull) +#define CVMX_PCI_INSTR_COUNT3 \ + (0x000000000000009Cull) +#define CVMX_PCI_INSTR_COUNTX(offset) \ + (0x0000000000000084ull + (((offset) & 3) * 8)) +#define CVMX_PCI_INT_ENB \ + (0x0000000000000038ull) +#define CVMX_PCI_INT_ENB2 \ + (0x00000000000001A0ull) +#define CVMX_PCI_INT_SUM \ + (0x0000000000000030ull) +#define CVMX_PCI_INT_SUM2 \ + (0x0000000000000198ull) +#define CVMX_PCI_MSI_RCV \ + (0x00000000000000F0ull) +#define CVMX_PCI_PKTS_SENT0 \ + (0x0000000000000040ull) +#define CVMX_PCI_PKTS_SENT1 \ + (0x0000000000000050ull) +#define CVMX_PCI_PKTS_SENT2 \ + (0x0000000000000060ull) +#define CVMX_PCI_PKTS_SENT3 \ + (0x0000000000000070ull) +#define CVMX_PCI_PKTS_SENTX(offset) \ + (0x0000000000000040ull + (((offset) & 3) * 16)) +#define CVMX_PCI_PKTS_SENT_INT_LEV0 \ + (0x0000000000000048ull) +#define CVMX_PCI_PKTS_SENT_INT_LEV1 \ + (0x0000000000000058ull) +#define CVMX_PCI_PKTS_SENT_INT_LEV2 \ + (0x0000000000000068ull) +#define CVMX_PCI_PKTS_SENT_INT_LEV3 \ + (0x0000000000000078ull) +#define CVMX_PCI_PKTS_SENT_INT_LEVX(offset) \ + (0x0000000000000048ull + (((offset) & 3) * 16)) +#define CVMX_PCI_PKTS_SENT_TIME0 \ + (0x000000000000004Cull) +#define CVMX_PCI_PKTS_SENT_TIME1 \ + (0x000000000000005Cull) +#define CVMX_PCI_PKTS_SENT_TIME2 \ + (0x000000000000006Cull) +#define CVMX_PCI_PKTS_SENT_TIME3 \ + (0x000000000000007Cull) +#define CVMX_PCI_PKTS_SENT_TIMEX(offset) \ + (0x000000000000004Cull + (((offset) & 3) * 16)) +#define CVMX_PCI_PKT_CREDITS0 \ + (0x0000000000000044ull) +#define CVMX_PCI_PKT_CREDITS1 \ + (0x0000000000000054ull) +#define CVMX_PCI_PKT_CREDITS2 \ + (0x0000000000000064ull) +#define CVMX_PCI_PKT_CREDITS3 \ + (0x0000000000000074ull) +#define CVMX_PCI_PKT_CREDITSX(offset) \ + (0x0000000000000044ull + (((offset) & 3) * 16)) +#define CVMX_PCI_READ_CMD_6 \ + (0x0000000000000180ull) +#define CVMX_PCI_READ_CMD_C \ + (0x0000000000000184ull) +#define CVMX_PCI_READ_CMD_E \ + (0x0000000000000188ull) +#define CVMX_PCI_READ_TIMEOUT \ + CVMX_ADD_IO_SEG(0x00011F00000000B0ull) +#define CVMX_PCI_SCM_REG \ + (0x00000000000001A8ull) +#define CVMX_PCI_TSR_REG \ + (0x00000000000001B0ull) +#define CVMX_PCI_WIN_RD_ADDR \ + (0x0000000000000008ull) +#define CVMX_PCI_WIN_RD_DATA \ + (0x0000000000000020ull) +#define CVMX_PCI_WIN_WR_ADDR \ + (0x0000000000000000ull) +#define CVMX_PCI_WIN_WR_DATA \ + (0x0000000000000010ull) +#define CVMX_PCI_WIN_WR_MASK \ + (0x0000000000000018ull) union cvmx_pci_bar1_indexx { uint32_t u32; diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h index f8cb88902efb..75574c918942 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,83 +28,158 @@ #ifndef __CVMX_PCIERCX_DEFS_H__ #define __CVMX_PCIERCX_DEFS_H__ -#define CVMX_PCIERCX_CFG000(block_id) (0x0000000000000000ull) -#define CVMX_PCIERCX_CFG001(block_id) (0x0000000000000004ull) -#define CVMX_PCIERCX_CFG002(block_id) (0x0000000000000008ull) -#define CVMX_PCIERCX_CFG003(block_id) (0x000000000000000Cull) -#define CVMX_PCIERCX_CFG004(block_id) (0x0000000000000010ull) -#define CVMX_PCIERCX_CFG005(block_id) (0x0000000000000014ull) -#define CVMX_PCIERCX_CFG006(block_id) (0x0000000000000018ull) -#define CVMX_PCIERCX_CFG007(block_id) (0x000000000000001Cull) -#define CVMX_PCIERCX_CFG008(block_id) (0x0000000000000020ull) -#define CVMX_PCIERCX_CFG009(block_id) (0x0000000000000024ull) -#define CVMX_PCIERCX_CFG010(block_id) (0x0000000000000028ull) -#define CVMX_PCIERCX_CFG011(block_id) (0x000000000000002Cull) -#define CVMX_PCIERCX_CFG012(block_id) (0x0000000000000030ull) -#define CVMX_PCIERCX_CFG013(block_id) (0x0000000000000034ull) -#define CVMX_PCIERCX_CFG014(block_id) (0x0000000000000038ull) -#define CVMX_PCIERCX_CFG015(block_id) (0x000000000000003Cull) -#define CVMX_PCIERCX_CFG016(block_id) (0x0000000000000040ull) -#define CVMX_PCIERCX_CFG017(block_id) (0x0000000000000044ull) -#define CVMX_PCIERCX_CFG020(block_id) (0x0000000000000050ull) -#define CVMX_PCIERCX_CFG021(block_id) (0x0000000000000054ull) -#define CVMX_PCIERCX_CFG022(block_id) (0x0000000000000058ull) -#define CVMX_PCIERCX_CFG023(block_id) (0x000000000000005Cull) -#define CVMX_PCIERCX_CFG028(block_id) (0x0000000000000070ull) -#define CVMX_PCIERCX_CFG029(block_id) (0x0000000000000074ull) -#define CVMX_PCIERCX_CFG030(block_id) (0x0000000000000078ull) -#define CVMX_PCIERCX_CFG031(block_id) (0x000000000000007Cull) -#define CVMX_PCIERCX_CFG032(block_id) (0x0000000000000080ull) -#define CVMX_PCIERCX_CFG033(block_id) (0x0000000000000084ull) -#define CVMX_PCIERCX_CFG034(block_id) (0x0000000000000088ull) -#define CVMX_PCIERCX_CFG035(block_id) (0x000000000000008Cull) -#define CVMX_PCIERCX_CFG036(block_id) (0x0000000000000090ull) -#define CVMX_PCIERCX_CFG037(block_id) (0x0000000000000094ull) -#define CVMX_PCIERCX_CFG038(block_id) (0x0000000000000098ull) -#define CVMX_PCIERCX_CFG039(block_id) (0x000000000000009Cull) -#define CVMX_PCIERCX_CFG040(block_id) (0x00000000000000A0ull) -#define CVMX_PCIERCX_CFG041(block_id) (0x00000000000000A4ull) -#define CVMX_PCIERCX_CFG042(block_id) (0x00000000000000A8ull) -#define CVMX_PCIERCX_CFG064(block_id) (0x0000000000000100ull) -#define CVMX_PCIERCX_CFG065(block_id) (0x0000000000000104ull) -#define CVMX_PCIERCX_CFG066(block_id) (0x0000000000000108ull) -#define CVMX_PCIERCX_CFG067(block_id) (0x000000000000010Cull) -#define CVMX_PCIERCX_CFG068(block_id) (0x0000000000000110ull) -#define CVMX_PCIERCX_CFG069(block_id) (0x0000000000000114ull) -#define CVMX_PCIERCX_CFG070(block_id) (0x0000000000000118ull) -#define CVMX_PCIERCX_CFG071(block_id) (0x000000000000011Cull) -#define CVMX_PCIERCX_CFG072(block_id) (0x0000000000000120ull) -#define CVMX_PCIERCX_CFG073(block_id) (0x0000000000000124ull) -#define CVMX_PCIERCX_CFG074(block_id) (0x0000000000000128ull) -#define CVMX_PCIERCX_CFG075(block_id) (0x000000000000012Cull) -#define CVMX_PCIERCX_CFG076(block_id) (0x0000000000000130ull) -#define CVMX_PCIERCX_CFG077(block_id) (0x0000000000000134ull) -#define CVMX_PCIERCX_CFG448(block_id) (0x0000000000000700ull) -#define CVMX_PCIERCX_CFG449(block_id) (0x0000000000000704ull) -#define CVMX_PCIERCX_CFG450(block_id) (0x0000000000000708ull) -#define CVMX_PCIERCX_CFG451(block_id) (0x000000000000070Cull) -#define CVMX_PCIERCX_CFG452(block_id) (0x0000000000000710ull) -#define CVMX_PCIERCX_CFG453(block_id) (0x0000000000000714ull) -#define CVMX_PCIERCX_CFG454(block_id) (0x0000000000000718ull) -#define CVMX_PCIERCX_CFG455(block_id) (0x000000000000071Cull) -#define CVMX_PCIERCX_CFG456(block_id) (0x0000000000000720ull) -#define CVMX_PCIERCX_CFG458(block_id) (0x0000000000000728ull) -#define CVMX_PCIERCX_CFG459(block_id) (0x000000000000072Cull) -#define CVMX_PCIERCX_CFG460(block_id) (0x0000000000000730ull) -#define CVMX_PCIERCX_CFG461(block_id) (0x0000000000000734ull) -#define CVMX_PCIERCX_CFG462(block_id) (0x0000000000000738ull) -#define CVMX_PCIERCX_CFG463(block_id) (0x000000000000073Cull) -#define CVMX_PCIERCX_CFG464(block_id) (0x0000000000000740ull) -#define CVMX_PCIERCX_CFG465(block_id) (0x0000000000000744ull) -#define CVMX_PCIERCX_CFG466(block_id) (0x0000000000000748ull) -#define CVMX_PCIERCX_CFG467(block_id) (0x000000000000074Cull) -#define CVMX_PCIERCX_CFG468(block_id) (0x0000000000000750ull) -#define CVMX_PCIERCX_CFG490(block_id) (0x00000000000007A8ull) -#define CVMX_PCIERCX_CFG491(block_id) (0x00000000000007ACull) -#define CVMX_PCIERCX_CFG492(block_id) (0x00000000000007B0ull) -#define CVMX_PCIERCX_CFG515(block_id) (0x000000000000080Cull) -#define CVMX_PCIERCX_CFG516(block_id) (0x0000000000000810ull) -#define CVMX_PCIERCX_CFG517(block_id) (0x0000000000000814ull) +#define CVMX_PCIERCX_CFG000(offset) \ + (0x0000000000000000ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG001(offset) \ + (0x0000000000000004ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG002(offset) \ + (0x0000000000000008ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG003(offset) \ + (0x000000000000000Cull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG004(offset) \ + (0x0000000000000010ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG005(offset) \ + (0x0000000000000014ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG006(offset) \ + (0x0000000000000018ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG007(offset) \ + (0x000000000000001Cull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG008(offset) \ + (0x0000000000000020ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG009(offset) \ + (0x0000000000000024ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG010(offset) \ + (0x0000000000000028ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG011(offset) \ + (0x000000000000002Cull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG012(offset) \ + (0x0000000000000030ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG013(offset) \ + (0x0000000000000034ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG014(offset) \ + (0x0000000000000038ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG015(offset) \ + (0x000000000000003Cull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG016(offset) \ + (0x0000000000000040ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG017(offset) \ + (0x0000000000000044ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG020(offset) \ + (0x0000000000000050ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG021(offset) \ + (0x0000000000000054ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG022(offset) \ + (0x0000000000000058ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG023(offset) \ + (0x000000000000005Cull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG028(offset) \ + (0x0000000000000070ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG029(offset) \ + (0x0000000000000074ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG030(offset) \ + (0x0000000000000078ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG031(offset) \ + (0x000000000000007Cull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG032(offset) \ + (0x0000000000000080ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG033(offset) \ + (0x0000000000000084ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG034(offset) \ + (0x0000000000000088ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG035(offset) \ + (0x000000000000008Cull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG036(offset) \ + (0x0000000000000090ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG037(offset) \ + (0x0000000000000094ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG038(offset) \ + (0x0000000000000098ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG039(offset) \ + (0x000000000000009Cull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG040(offset) \ + (0x00000000000000A0ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG041(offset) \ + (0x00000000000000A4ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG042(offset) \ + (0x00000000000000A8ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG064(offset) \ + (0x0000000000000100ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG065(offset) \ + (0x0000000000000104ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG066(offset) \ + (0x0000000000000108ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG067(offset) \ + (0x000000000000010Cull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG068(offset) \ + (0x0000000000000110ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG069(offset) \ + (0x0000000000000114ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG070(offset) \ + (0x0000000000000118ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG071(offset) \ + (0x000000000000011Cull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG072(offset) \ + (0x0000000000000120ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG073(offset) \ + (0x0000000000000124ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG074(offset) \ + (0x0000000000000128ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG075(offset) \ + (0x000000000000012Cull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG076(offset) \ + (0x0000000000000130ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG077(offset) \ + (0x0000000000000134ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG448(offset) \ + (0x0000000000000700ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG449(offset) \ + (0x0000000000000704ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG450(offset) \ + (0x0000000000000708ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG451(offset) \ + (0x000000000000070Cull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG452(offset) \ + (0x0000000000000710ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG453(offset) \ + (0x0000000000000714ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG454(offset) \ + (0x0000000000000718ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG455(offset) \ + (0x000000000000071Cull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG456(offset) \ + (0x0000000000000720ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG458(offset) \ + (0x0000000000000728ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG459(offset) \ + (0x000000000000072Cull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG460(offset) \ + (0x0000000000000730ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG461(offset) \ + (0x0000000000000734ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG462(offset) \ + (0x0000000000000738ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG463(offset) \ + (0x000000000000073Cull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG464(offset) \ + (0x0000000000000740ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG465(offset) \ + (0x0000000000000744ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG466(offset) \ + (0x0000000000000748ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG467(offset) \ + (0x000000000000074Cull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG468(offset) \ + (0x0000000000000750ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG490(offset) \ + (0x00000000000007A8ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG491(offset) \ + (0x00000000000007ACull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG492(offset) \ + (0x00000000000007B0ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG516(offset) \ + (0x0000000000000810ull + (((offset) & 1) * 0)) +#define CVMX_PCIERCX_CFG517(offset) \ + (0x0000000000000814ull + (((offset) & 1) * 0)) union cvmx_pciercx_cfg000 { uint32_t u32; @@ -116,8 +191,6 @@ union cvmx_pciercx_cfg000 { struct cvmx_pciercx_cfg000_s cn52xxp1; struct cvmx_pciercx_cfg000_s cn56xx; struct cvmx_pciercx_cfg000_s cn56xxp1; - struct cvmx_pciercx_cfg000_s cn63xx; - struct cvmx_pciercx_cfg000_s cn63xxp1; }; union cvmx_pciercx_cfg001 { @@ -152,8 +225,6 @@ union cvmx_pciercx_cfg001 { struct cvmx_pciercx_cfg001_s cn52xxp1; struct cvmx_pciercx_cfg001_s cn56xx; struct cvmx_pciercx_cfg001_s cn56xxp1; - struct cvmx_pciercx_cfg001_s cn63xx; - struct cvmx_pciercx_cfg001_s cn63xxp1; }; union cvmx_pciercx_cfg002 { @@ -168,8 +239,6 @@ union cvmx_pciercx_cfg002 { struct cvmx_pciercx_cfg002_s cn52xxp1; struct cvmx_pciercx_cfg002_s cn56xx; struct cvmx_pciercx_cfg002_s cn56xxp1; - struct cvmx_pciercx_cfg002_s cn63xx; - struct cvmx_pciercx_cfg002_s cn63xxp1; }; union cvmx_pciercx_cfg003 { @@ -185,8 +254,6 @@ union cvmx_pciercx_cfg003 { struct cvmx_pciercx_cfg003_s cn52xxp1; struct cvmx_pciercx_cfg003_s cn56xx; struct cvmx_pciercx_cfg003_s cn56xxp1; - struct cvmx_pciercx_cfg003_s cn63xx; - struct cvmx_pciercx_cfg003_s cn63xxp1; }; union cvmx_pciercx_cfg004 { @@ -198,8 +265,6 @@ union cvmx_pciercx_cfg004 { struct cvmx_pciercx_cfg004_s cn52xxp1; struct cvmx_pciercx_cfg004_s cn56xx; struct cvmx_pciercx_cfg004_s cn56xxp1; - struct cvmx_pciercx_cfg004_s cn63xx; - struct cvmx_pciercx_cfg004_s cn63xxp1; }; union cvmx_pciercx_cfg005 { @@ -211,8 +276,6 @@ union cvmx_pciercx_cfg005 { struct cvmx_pciercx_cfg005_s cn52xxp1; struct cvmx_pciercx_cfg005_s cn56xx; struct cvmx_pciercx_cfg005_s cn56xxp1; - struct cvmx_pciercx_cfg005_s cn63xx; - struct cvmx_pciercx_cfg005_s cn63xxp1; }; union cvmx_pciercx_cfg006 { @@ -227,8 +290,6 @@ union cvmx_pciercx_cfg006 { struct cvmx_pciercx_cfg006_s cn52xxp1; struct cvmx_pciercx_cfg006_s cn56xx; struct cvmx_pciercx_cfg006_s cn56xxp1; - struct cvmx_pciercx_cfg006_s cn63xx; - struct cvmx_pciercx_cfg006_s cn63xxp1; }; union cvmx_pciercx_cfg007 { @@ -256,8 +317,6 @@ union cvmx_pciercx_cfg007 { struct cvmx_pciercx_cfg007_s cn52xxp1; struct cvmx_pciercx_cfg007_s cn56xx; struct cvmx_pciercx_cfg007_s cn56xxp1; - struct cvmx_pciercx_cfg007_s cn63xx; - struct cvmx_pciercx_cfg007_s cn63xxp1; }; union cvmx_pciercx_cfg008 { @@ -272,8 +331,6 @@ union cvmx_pciercx_cfg008 { struct cvmx_pciercx_cfg008_s cn52xxp1; struct cvmx_pciercx_cfg008_s cn56xx; struct cvmx_pciercx_cfg008_s cn56xxp1; - struct cvmx_pciercx_cfg008_s cn63xx; - struct cvmx_pciercx_cfg008_s cn63xxp1; }; union cvmx_pciercx_cfg009 { @@ -290,8 +347,6 @@ union cvmx_pciercx_cfg009 { struct cvmx_pciercx_cfg009_s cn52xxp1; struct cvmx_pciercx_cfg009_s cn56xx; struct cvmx_pciercx_cfg009_s cn56xxp1; - struct cvmx_pciercx_cfg009_s cn63xx; - struct cvmx_pciercx_cfg009_s cn63xxp1; }; union cvmx_pciercx_cfg010 { @@ -303,8 +358,6 @@ union cvmx_pciercx_cfg010 { struct cvmx_pciercx_cfg010_s cn52xxp1; struct cvmx_pciercx_cfg010_s cn56xx; struct cvmx_pciercx_cfg010_s cn56xxp1; - struct cvmx_pciercx_cfg010_s cn63xx; - struct cvmx_pciercx_cfg010_s cn63xxp1; }; union cvmx_pciercx_cfg011 { @@ -316,8 +369,6 @@ union cvmx_pciercx_cfg011 { struct cvmx_pciercx_cfg011_s cn52xxp1; struct cvmx_pciercx_cfg011_s cn56xx; struct cvmx_pciercx_cfg011_s cn56xxp1; - struct cvmx_pciercx_cfg011_s cn63xx; - struct cvmx_pciercx_cfg011_s cn63xxp1; }; union cvmx_pciercx_cfg012 { @@ -330,8 +381,6 @@ union cvmx_pciercx_cfg012 { struct cvmx_pciercx_cfg012_s cn52xxp1; struct cvmx_pciercx_cfg012_s cn56xx; struct cvmx_pciercx_cfg012_s cn56xxp1; - struct cvmx_pciercx_cfg012_s cn63xx; - struct cvmx_pciercx_cfg012_s cn63xxp1; }; union cvmx_pciercx_cfg013 { @@ -344,8 +393,6 @@ union cvmx_pciercx_cfg013 { struct cvmx_pciercx_cfg013_s cn52xxp1; struct cvmx_pciercx_cfg013_s cn56xx; struct cvmx_pciercx_cfg013_s cn56xxp1; - struct cvmx_pciercx_cfg013_s cn63xx; - struct cvmx_pciercx_cfg013_s cn63xxp1; }; union cvmx_pciercx_cfg014 { @@ -357,8 +404,6 @@ union cvmx_pciercx_cfg014 { struct cvmx_pciercx_cfg014_s cn52xxp1; struct cvmx_pciercx_cfg014_s cn56xx; struct cvmx_pciercx_cfg014_s cn56xxp1; - struct cvmx_pciercx_cfg014_s cn63xx; - struct cvmx_pciercx_cfg014_s cn63xxp1; }; union cvmx_pciercx_cfg015 { @@ -384,8 +429,6 @@ union cvmx_pciercx_cfg015 { struct cvmx_pciercx_cfg015_s cn52xxp1; struct cvmx_pciercx_cfg015_s cn56xx; struct cvmx_pciercx_cfg015_s cn56xxp1; - struct cvmx_pciercx_cfg015_s cn63xx; - struct cvmx_pciercx_cfg015_s cn63xxp1; }; union cvmx_pciercx_cfg016 { @@ -406,8 +449,6 @@ union cvmx_pciercx_cfg016 { struct cvmx_pciercx_cfg016_s cn52xxp1; struct cvmx_pciercx_cfg016_s cn56xx; struct cvmx_pciercx_cfg016_s cn56xxp1; - struct cvmx_pciercx_cfg016_s cn63xx; - struct cvmx_pciercx_cfg016_s cn63xxp1; }; union cvmx_pciercx_cfg017 { @@ -430,8 +471,6 @@ union cvmx_pciercx_cfg017 { struct cvmx_pciercx_cfg017_s cn52xxp1; struct cvmx_pciercx_cfg017_s cn56xx; struct cvmx_pciercx_cfg017_s cn56xxp1; - struct cvmx_pciercx_cfg017_s cn63xx; - struct cvmx_pciercx_cfg017_s cn63xxp1; }; union cvmx_pciercx_cfg020 { @@ -449,8 +488,6 @@ union cvmx_pciercx_cfg020 { struct cvmx_pciercx_cfg020_s cn52xxp1; struct cvmx_pciercx_cfg020_s cn56xx; struct cvmx_pciercx_cfg020_s cn56xxp1; - struct cvmx_pciercx_cfg020_s cn63xx; - struct cvmx_pciercx_cfg020_s cn63xxp1; }; union cvmx_pciercx_cfg021 { @@ -463,8 +500,6 @@ union cvmx_pciercx_cfg021 { struct cvmx_pciercx_cfg021_s cn52xxp1; struct cvmx_pciercx_cfg021_s cn56xx; struct cvmx_pciercx_cfg021_s cn56xxp1; - struct cvmx_pciercx_cfg021_s cn63xx; - struct cvmx_pciercx_cfg021_s cn63xxp1; }; union cvmx_pciercx_cfg022 { @@ -476,8 +511,6 @@ union cvmx_pciercx_cfg022 { struct cvmx_pciercx_cfg022_s cn52xxp1; struct cvmx_pciercx_cfg022_s cn56xx; struct cvmx_pciercx_cfg022_s cn56xxp1; - struct cvmx_pciercx_cfg022_s cn63xx; - struct cvmx_pciercx_cfg022_s cn63xxp1; }; union cvmx_pciercx_cfg023 { @@ -490,8 +523,6 @@ union cvmx_pciercx_cfg023 { struct cvmx_pciercx_cfg023_s cn52xxp1; struct cvmx_pciercx_cfg023_s cn56xx; struct cvmx_pciercx_cfg023_s cn56xxp1; - struct cvmx_pciercx_cfg023_s cn63xx; - struct cvmx_pciercx_cfg023_s cn63xxp1; }; union cvmx_pciercx_cfg028 { @@ -509,8 +540,6 @@ union cvmx_pciercx_cfg028 { struct cvmx_pciercx_cfg028_s cn52xxp1; struct cvmx_pciercx_cfg028_s cn56xx; struct cvmx_pciercx_cfg028_s cn56xxp1; - struct cvmx_pciercx_cfg028_s cn63xx; - struct cvmx_pciercx_cfg028_s cn63xxp1; }; union cvmx_pciercx_cfg029 { @@ -532,8 +561,6 @@ union cvmx_pciercx_cfg029 { struct cvmx_pciercx_cfg029_s cn52xxp1; struct cvmx_pciercx_cfg029_s cn56xx; struct cvmx_pciercx_cfg029_s cn56xxp1; - struct cvmx_pciercx_cfg029_s cn63xx; - struct cvmx_pciercx_cfg029_s cn63xxp1; }; union cvmx_pciercx_cfg030 { @@ -563,8 +590,6 @@ union cvmx_pciercx_cfg030 { struct cvmx_pciercx_cfg030_s cn52xxp1; struct cvmx_pciercx_cfg030_s cn56xx; struct cvmx_pciercx_cfg030_s cn56xxp1; - struct cvmx_pciercx_cfg030_s cn63xx; - struct cvmx_pciercx_cfg030_s cn63xxp1; }; union cvmx_pciercx_cfg031 { @@ -586,8 +611,6 @@ union cvmx_pciercx_cfg031 { struct cvmx_pciercx_cfg031_s cn52xxp1; struct cvmx_pciercx_cfg031_s cn56xx; struct cvmx_pciercx_cfg031_s cn56xxp1; - struct cvmx_pciercx_cfg031_s cn63xx; - struct cvmx_pciercx_cfg031_s cn63xxp1; }; union cvmx_pciercx_cfg032 { @@ -618,8 +641,6 @@ union cvmx_pciercx_cfg032 { struct cvmx_pciercx_cfg032_s cn52xxp1; struct cvmx_pciercx_cfg032_s cn56xx; struct cvmx_pciercx_cfg032_s cn56xxp1; - struct cvmx_pciercx_cfg032_s cn63xx; - struct cvmx_pciercx_cfg032_s cn63xxp1; }; union cvmx_pciercx_cfg033 { @@ -642,8 +663,6 @@ union cvmx_pciercx_cfg033 { struct cvmx_pciercx_cfg033_s cn52xxp1; struct cvmx_pciercx_cfg033_s cn56xx; struct cvmx_pciercx_cfg033_s cn56xxp1; - struct cvmx_pciercx_cfg033_s cn63xx; - struct cvmx_pciercx_cfg033_s cn63xxp1; }; union cvmx_pciercx_cfg034 { @@ -676,8 +695,6 @@ union cvmx_pciercx_cfg034 { struct cvmx_pciercx_cfg034_s cn52xxp1; struct cvmx_pciercx_cfg034_s cn56xx; struct cvmx_pciercx_cfg034_s cn56xxp1; - struct cvmx_pciercx_cfg034_s cn63xx; - struct cvmx_pciercx_cfg034_s cn63xxp1; }; union cvmx_pciercx_cfg035 { @@ -696,8 +713,6 @@ union cvmx_pciercx_cfg035 { struct cvmx_pciercx_cfg035_s cn52xxp1; struct cvmx_pciercx_cfg035_s cn56xx; struct cvmx_pciercx_cfg035_s cn56xxp1; - struct cvmx_pciercx_cfg035_s cn63xx; - struct cvmx_pciercx_cfg035_s cn63xxp1; }; union cvmx_pciercx_cfg036 { @@ -712,8 +727,6 @@ union cvmx_pciercx_cfg036 { struct cvmx_pciercx_cfg036_s cn52xxp1; struct cvmx_pciercx_cfg036_s cn56xx; struct cvmx_pciercx_cfg036_s cn56xxp1; - struct cvmx_pciercx_cfg036_s cn63xx; - struct cvmx_pciercx_cfg036_s cn63xxp1; }; union cvmx_pciercx_cfg037 { @@ -727,8 +740,6 @@ union cvmx_pciercx_cfg037 { struct cvmx_pciercx_cfg037_s cn52xxp1; struct cvmx_pciercx_cfg037_s cn56xx; struct cvmx_pciercx_cfg037_s cn56xxp1; - struct cvmx_pciercx_cfg037_s cn63xx; - struct cvmx_pciercx_cfg037_s cn63xxp1; }; union cvmx_pciercx_cfg038 { @@ -742,51 +753,28 @@ union cvmx_pciercx_cfg038 { struct cvmx_pciercx_cfg038_s cn52xxp1; struct cvmx_pciercx_cfg038_s cn56xx; struct cvmx_pciercx_cfg038_s cn56xxp1; - struct cvmx_pciercx_cfg038_s cn63xx; - struct cvmx_pciercx_cfg038_s cn63xxp1; }; union cvmx_pciercx_cfg039 { uint32_t u32; struct cvmx_pciercx_cfg039_s { - uint32_t reserved_9_31:23; - uint32_t cls:1; - uint32_t slsv:7; - uint32_t reserved_0_0:1; - } s; - struct cvmx_pciercx_cfg039_cn52xx { uint32_t reserved_0_31:32; - } cn52xx; - struct cvmx_pciercx_cfg039_cn52xx cn52xxp1; - struct cvmx_pciercx_cfg039_cn52xx cn56xx; - struct cvmx_pciercx_cfg039_cn52xx cn56xxp1; - struct cvmx_pciercx_cfg039_s cn63xx; - struct cvmx_pciercx_cfg039_cn52xx cn63xxp1; + } s; + struct cvmx_pciercx_cfg039_s cn52xx; + struct cvmx_pciercx_cfg039_s cn52xxp1; + struct cvmx_pciercx_cfg039_s cn56xx; + struct cvmx_pciercx_cfg039_s cn56xxp1; }; union cvmx_pciercx_cfg040 { uint32_t u32; struct cvmx_pciercx_cfg040_s { - uint32_t reserved_17_31:15; - uint32_t cdl:1; - uint32_t reserved_13_15:3; - uint32_t cde:1; - uint32_t csos:1; - uint32_t emc:1; - uint32_t tm:3; - uint32_t sde:1; - uint32_t hasd:1; - uint32_t ec:1; - uint32_t tls:4; - } s; - struct cvmx_pciercx_cfg040_cn52xx { uint32_t reserved_0_31:32; - } cn52xx; - struct cvmx_pciercx_cfg040_cn52xx cn52xxp1; - struct cvmx_pciercx_cfg040_cn52xx cn56xx; - struct cvmx_pciercx_cfg040_cn52xx cn56xxp1; - struct cvmx_pciercx_cfg040_s cn63xx; - struct cvmx_pciercx_cfg040_s cn63xxp1; + } s; + struct cvmx_pciercx_cfg040_s cn52xx; + struct cvmx_pciercx_cfg040_s cn52xxp1; + struct cvmx_pciercx_cfg040_s cn56xx; + struct cvmx_pciercx_cfg040_s cn56xxp1; }; union cvmx_pciercx_cfg041 { @@ -798,8 +786,6 @@ union cvmx_pciercx_cfg041 { struct cvmx_pciercx_cfg041_s cn52xxp1; struct cvmx_pciercx_cfg041_s cn56xx; struct cvmx_pciercx_cfg041_s cn56xxp1; - struct cvmx_pciercx_cfg041_s cn63xx; - struct cvmx_pciercx_cfg041_s cn63xxp1; }; union cvmx_pciercx_cfg042 { @@ -811,8 +797,6 @@ union cvmx_pciercx_cfg042 { struct cvmx_pciercx_cfg042_s cn52xxp1; struct cvmx_pciercx_cfg042_s cn56xx; struct cvmx_pciercx_cfg042_s cn56xxp1; - struct cvmx_pciercx_cfg042_s cn63xx; - struct cvmx_pciercx_cfg042_s cn63xxp1; }; union cvmx_pciercx_cfg064 { @@ -826,8 +810,6 @@ union cvmx_pciercx_cfg064 { struct cvmx_pciercx_cfg064_s cn52xxp1; struct cvmx_pciercx_cfg064_s cn56xx; struct cvmx_pciercx_cfg064_s cn56xxp1; - struct cvmx_pciercx_cfg064_s cn63xx; - struct cvmx_pciercx_cfg064_s cn63xxp1; }; union cvmx_pciercx_cfg065 { @@ -852,8 +834,6 @@ union cvmx_pciercx_cfg065 { struct cvmx_pciercx_cfg065_s cn52xxp1; struct cvmx_pciercx_cfg065_s cn56xx; struct cvmx_pciercx_cfg065_s cn56xxp1; - struct cvmx_pciercx_cfg065_s cn63xx; - struct cvmx_pciercx_cfg065_s cn63xxp1; }; union cvmx_pciercx_cfg066 { @@ -878,8 +858,6 @@ union cvmx_pciercx_cfg066 { struct cvmx_pciercx_cfg066_s cn52xxp1; struct cvmx_pciercx_cfg066_s cn56xx; struct cvmx_pciercx_cfg066_s cn56xxp1; - struct cvmx_pciercx_cfg066_s cn63xx; - struct cvmx_pciercx_cfg066_s cn63xxp1; }; union cvmx_pciercx_cfg067 { @@ -904,8 +882,6 @@ union cvmx_pciercx_cfg067 { struct cvmx_pciercx_cfg067_s cn52xxp1; struct cvmx_pciercx_cfg067_s cn56xx; struct cvmx_pciercx_cfg067_s cn56xxp1; - struct cvmx_pciercx_cfg067_s cn63xx; - struct cvmx_pciercx_cfg067_s cn63xxp1; }; union cvmx_pciercx_cfg068 { @@ -925,8 +901,6 @@ union cvmx_pciercx_cfg068 { struct cvmx_pciercx_cfg068_s cn52xxp1; struct cvmx_pciercx_cfg068_s cn56xx; struct cvmx_pciercx_cfg068_s cn56xxp1; - struct cvmx_pciercx_cfg068_s cn63xx; - struct cvmx_pciercx_cfg068_s cn63xxp1; }; union cvmx_pciercx_cfg069 { @@ -946,8 +920,6 @@ union cvmx_pciercx_cfg069 { struct cvmx_pciercx_cfg069_s cn52xxp1; struct cvmx_pciercx_cfg069_s cn56xx; struct cvmx_pciercx_cfg069_s cn56xxp1; - struct cvmx_pciercx_cfg069_s cn63xx; - struct cvmx_pciercx_cfg069_s cn63xxp1; }; union cvmx_pciercx_cfg070 { @@ -964,8 +936,6 @@ union cvmx_pciercx_cfg070 { struct cvmx_pciercx_cfg070_s cn52xxp1; struct cvmx_pciercx_cfg070_s cn56xx; struct cvmx_pciercx_cfg070_s cn56xxp1; - struct cvmx_pciercx_cfg070_s cn63xx; - struct cvmx_pciercx_cfg070_s cn63xxp1; }; union cvmx_pciercx_cfg071 { @@ -977,8 +947,6 @@ union cvmx_pciercx_cfg071 { struct cvmx_pciercx_cfg071_s cn52xxp1; struct cvmx_pciercx_cfg071_s cn56xx; struct cvmx_pciercx_cfg071_s cn56xxp1; - struct cvmx_pciercx_cfg071_s cn63xx; - struct cvmx_pciercx_cfg071_s cn63xxp1; }; union cvmx_pciercx_cfg072 { @@ -990,8 +958,6 @@ union cvmx_pciercx_cfg072 { struct cvmx_pciercx_cfg072_s cn52xxp1; struct cvmx_pciercx_cfg072_s cn56xx; struct cvmx_pciercx_cfg072_s cn56xxp1; - struct cvmx_pciercx_cfg072_s cn63xx; - struct cvmx_pciercx_cfg072_s cn63xxp1; }; union cvmx_pciercx_cfg073 { @@ -1003,8 +969,6 @@ union cvmx_pciercx_cfg073 { struct cvmx_pciercx_cfg073_s cn52xxp1; struct cvmx_pciercx_cfg073_s cn56xx; struct cvmx_pciercx_cfg073_s cn56xxp1; - struct cvmx_pciercx_cfg073_s cn63xx; - struct cvmx_pciercx_cfg073_s cn63xxp1; }; union cvmx_pciercx_cfg074 { @@ -1016,8 +980,6 @@ union cvmx_pciercx_cfg074 { struct cvmx_pciercx_cfg074_s cn52xxp1; struct cvmx_pciercx_cfg074_s cn56xx; struct cvmx_pciercx_cfg074_s cn56xxp1; - struct cvmx_pciercx_cfg074_s cn63xx; - struct cvmx_pciercx_cfg074_s cn63xxp1; }; union cvmx_pciercx_cfg075 { @@ -1032,8 +994,6 @@ union cvmx_pciercx_cfg075 { struct cvmx_pciercx_cfg075_s cn52xxp1; struct cvmx_pciercx_cfg075_s cn56xx; struct cvmx_pciercx_cfg075_s cn56xxp1; - struct cvmx_pciercx_cfg075_s cn63xx; - struct cvmx_pciercx_cfg075_s cn63xxp1; }; union cvmx_pciercx_cfg076 { @@ -1053,8 +1013,6 @@ union cvmx_pciercx_cfg076 { struct cvmx_pciercx_cfg076_s cn52xxp1; struct cvmx_pciercx_cfg076_s cn56xx; struct cvmx_pciercx_cfg076_s cn56xxp1; - struct cvmx_pciercx_cfg076_s cn63xx; - struct cvmx_pciercx_cfg076_s cn63xxp1; }; union cvmx_pciercx_cfg077 { @@ -1067,8 +1025,6 @@ union cvmx_pciercx_cfg077 { struct cvmx_pciercx_cfg077_s cn52xxp1; struct cvmx_pciercx_cfg077_s cn56xx; struct cvmx_pciercx_cfg077_s cn56xxp1; - struct cvmx_pciercx_cfg077_s cn63xx; - struct cvmx_pciercx_cfg077_s cn63xxp1; }; union cvmx_pciercx_cfg448 { @@ -1081,8 +1037,6 @@ union cvmx_pciercx_cfg448 { struct cvmx_pciercx_cfg448_s cn52xxp1; struct cvmx_pciercx_cfg448_s cn56xx; struct cvmx_pciercx_cfg448_s cn56xxp1; - struct cvmx_pciercx_cfg448_s cn63xx; - struct cvmx_pciercx_cfg448_s cn63xxp1; }; union cvmx_pciercx_cfg449 { @@ -1094,8 +1048,6 @@ union cvmx_pciercx_cfg449 { struct cvmx_pciercx_cfg449_s cn52xxp1; struct cvmx_pciercx_cfg449_s cn56xx; struct cvmx_pciercx_cfg449_s cn56xxp1; - struct cvmx_pciercx_cfg449_s cn63xx; - struct cvmx_pciercx_cfg449_s cn63xxp1; }; union cvmx_pciercx_cfg450 { @@ -1112,8 +1064,6 @@ union cvmx_pciercx_cfg450 { struct cvmx_pciercx_cfg450_s cn52xxp1; struct cvmx_pciercx_cfg450_s cn56xx; struct cvmx_pciercx_cfg450_s cn56xxp1; - struct cvmx_pciercx_cfg450_s cn63xx; - struct cvmx_pciercx_cfg450_s cn63xxp1; }; union cvmx_pciercx_cfg451 { @@ -1130,8 +1080,6 @@ union cvmx_pciercx_cfg451 { struct cvmx_pciercx_cfg451_s cn52xxp1; struct cvmx_pciercx_cfg451_s cn56xx; struct cvmx_pciercx_cfg451_s cn56xxp1; - struct cvmx_pciercx_cfg451_s cn63xx; - struct cvmx_pciercx_cfg451_s cn63xxp1; }; union cvmx_pciercx_cfg452 { @@ -1155,8 +1103,6 @@ union cvmx_pciercx_cfg452 { struct cvmx_pciercx_cfg452_s cn52xxp1; struct cvmx_pciercx_cfg452_s cn56xx; struct cvmx_pciercx_cfg452_s cn56xxp1; - struct cvmx_pciercx_cfg452_s cn63xx; - struct cvmx_pciercx_cfg452_s cn63xxp1; }; union cvmx_pciercx_cfg453 { @@ -1172,8 +1118,6 @@ union cvmx_pciercx_cfg453 { struct cvmx_pciercx_cfg453_s cn52xxp1; struct cvmx_pciercx_cfg453_s cn56xx; struct cvmx_pciercx_cfg453_s cn56xxp1; - struct cvmx_pciercx_cfg453_s cn63xx; - struct cvmx_pciercx_cfg453_s cn63xxp1; }; union cvmx_pciercx_cfg454 { @@ -1192,8 +1136,6 @@ union cvmx_pciercx_cfg454 { struct cvmx_pciercx_cfg454_s cn52xxp1; struct cvmx_pciercx_cfg454_s cn56xx; struct cvmx_pciercx_cfg454_s cn56xxp1; - struct cvmx_pciercx_cfg454_s cn63xx; - struct cvmx_pciercx_cfg454_s cn63xxp1; }; union cvmx_pciercx_cfg455 { @@ -1223,8 +1165,6 @@ union cvmx_pciercx_cfg455 { struct cvmx_pciercx_cfg455_s cn52xxp1; struct cvmx_pciercx_cfg455_s cn56xx; struct cvmx_pciercx_cfg455_s cn56xxp1; - struct cvmx_pciercx_cfg455_s cn63xx; - struct cvmx_pciercx_cfg455_s cn63xxp1; }; union cvmx_pciercx_cfg456 { @@ -1238,8 +1178,6 @@ union cvmx_pciercx_cfg456 { struct cvmx_pciercx_cfg456_s cn52xxp1; struct cvmx_pciercx_cfg456_s cn56xx; struct cvmx_pciercx_cfg456_s cn56xxp1; - struct cvmx_pciercx_cfg456_s cn63xx; - struct cvmx_pciercx_cfg456_s cn63xxp1; }; union cvmx_pciercx_cfg458 { @@ -1251,8 +1189,6 @@ union cvmx_pciercx_cfg458 { struct cvmx_pciercx_cfg458_s cn52xxp1; struct cvmx_pciercx_cfg458_s cn56xx; struct cvmx_pciercx_cfg458_s cn56xxp1; - struct cvmx_pciercx_cfg458_s cn63xx; - struct cvmx_pciercx_cfg458_s cn63xxp1; }; union cvmx_pciercx_cfg459 { @@ -1264,8 +1200,6 @@ union cvmx_pciercx_cfg459 { struct cvmx_pciercx_cfg459_s cn52xxp1; struct cvmx_pciercx_cfg459_s cn56xx; struct cvmx_pciercx_cfg459_s cn56xxp1; - struct cvmx_pciercx_cfg459_s cn63xx; - struct cvmx_pciercx_cfg459_s cn63xxp1; }; union cvmx_pciercx_cfg460 { @@ -1279,8 +1213,6 @@ union cvmx_pciercx_cfg460 { struct cvmx_pciercx_cfg460_s cn52xxp1; struct cvmx_pciercx_cfg460_s cn56xx; struct cvmx_pciercx_cfg460_s cn56xxp1; - struct cvmx_pciercx_cfg460_s cn63xx; - struct cvmx_pciercx_cfg460_s cn63xxp1; }; union cvmx_pciercx_cfg461 { @@ -1294,8 +1226,6 @@ union cvmx_pciercx_cfg461 { struct cvmx_pciercx_cfg461_s cn52xxp1; struct cvmx_pciercx_cfg461_s cn56xx; struct cvmx_pciercx_cfg461_s cn56xxp1; - struct cvmx_pciercx_cfg461_s cn63xx; - struct cvmx_pciercx_cfg461_s cn63xxp1; }; union cvmx_pciercx_cfg462 { @@ -1309,8 +1239,6 @@ union cvmx_pciercx_cfg462 { struct cvmx_pciercx_cfg462_s cn52xxp1; struct cvmx_pciercx_cfg462_s cn56xx; struct cvmx_pciercx_cfg462_s cn56xxp1; - struct cvmx_pciercx_cfg462_s cn63xx; - struct cvmx_pciercx_cfg462_s cn63xxp1; }; union cvmx_pciercx_cfg463 { @@ -1325,8 +1253,6 @@ union cvmx_pciercx_cfg463 { struct cvmx_pciercx_cfg463_s cn52xxp1; struct cvmx_pciercx_cfg463_s cn56xx; struct cvmx_pciercx_cfg463_s cn56xxp1; - struct cvmx_pciercx_cfg463_s cn63xx; - struct cvmx_pciercx_cfg463_s cn63xxp1; }; union cvmx_pciercx_cfg464 { @@ -1341,8 +1267,6 @@ union cvmx_pciercx_cfg464 { struct cvmx_pciercx_cfg464_s cn52xxp1; struct cvmx_pciercx_cfg464_s cn56xx; struct cvmx_pciercx_cfg464_s cn56xxp1; - struct cvmx_pciercx_cfg464_s cn63xx; - struct cvmx_pciercx_cfg464_s cn63xxp1; }; union cvmx_pciercx_cfg465 { @@ -1357,8 +1281,6 @@ union cvmx_pciercx_cfg465 { struct cvmx_pciercx_cfg465_s cn52xxp1; struct cvmx_pciercx_cfg465_s cn56xx; struct cvmx_pciercx_cfg465_s cn56xxp1; - struct cvmx_pciercx_cfg465_s cn63xx; - struct cvmx_pciercx_cfg465_s cn63xxp1; }; union cvmx_pciercx_cfg466 { @@ -1376,8 +1298,6 @@ union cvmx_pciercx_cfg466 { struct cvmx_pciercx_cfg466_s cn52xxp1; struct cvmx_pciercx_cfg466_s cn56xx; struct cvmx_pciercx_cfg466_s cn56xxp1; - struct cvmx_pciercx_cfg466_s cn63xx; - struct cvmx_pciercx_cfg466_s cn63xxp1; }; union cvmx_pciercx_cfg467 { @@ -1393,8 +1313,6 @@ union cvmx_pciercx_cfg467 { struct cvmx_pciercx_cfg467_s cn52xxp1; struct cvmx_pciercx_cfg467_s cn56xx; struct cvmx_pciercx_cfg467_s cn56xxp1; - struct cvmx_pciercx_cfg467_s cn63xx; - struct cvmx_pciercx_cfg467_s cn63xxp1; }; union cvmx_pciercx_cfg468 { @@ -1410,8 +1328,6 @@ union cvmx_pciercx_cfg468 { struct cvmx_pciercx_cfg468_s cn52xxp1; struct cvmx_pciercx_cfg468_s cn56xx; struct cvmx_pciercx_cfg468_s cn56xxp1; - struct cvmx_pciercx_cfg468_s cn63xx; - struct cvmx_pciercx_cfg468_s cn63xxp1; }; union cvmx_pciercx_cfg490 { @@ -1426,8 +1342,6 @@ union cvmx_pciercx_cfg490 { struct cvmx_pciercx_cfg490_s cn52xxp1; struct cvmx_pciercx_cfg490_s cn56xx; struct cvmx_pciercx_cfg490_s cn56xxp1; - struct cvmx_pciercx_cfg490_s cn63xx; - struct cvmx_pciercx_cfg490_s cn63xxp1; }; union cvmx_pciercx_cfg491 { @@ -1442,8 +1356,6 @@ union cvmx_pciercx_cfg491 { struct cvmx_pciercx_cfg491_s cn52xxp1; struct cvmx_pciercx_cfg491_s cn56xx; struct cvmx_pciercx_cfg491_s cn56xxp1; - struct cvmx_pciercx_cfg491_s cn63xx; - struct cvmx_pciercx_cfg491_s cn63xxp1; }; union cvmx_pciercx_cfg492 { @@ -1458,23 +1370,6 @@ union cvmx_pciercx_cfg492 { struct cvmx_pciercx_cfg492_s cn52xxp1; struct cvmx_pciercx_cfg492_s cn56xx; struct cvmx_pciercx_cfg492_s cn56xxp1; - struct cvmx_pciercx_cfg492_s cn63xx; - struct cvmx_pciercx_cfg492_s cn63xxp1; -}; - -union cvmx_pciercx_cfg515 { - uint32_t u32; - struct cvmx_pciercx_cfg515_s { - uint32_t reserved_21_31:11; - uint32_t s_d_e:1; - uint32_t ctcrb:1; - uint32_t cpyts:1; - uint32_t dsc:1; - uint32_t le:9; - uint32_t n_fts:8; - } s; - struct cvmx_pciercx_cfg515_s cn63xx; - struct cvmx_pciercx_cfg515_s cn63xxp1; }; union cvmx_pciercx_cfg516 { @@ -1486,8 +1381,6 @@ union cvmx_pciercx_cfg516 { struct cvmx_pciercx_cfg516_s cn52xxp1; struct cvmx_pciercx_cfg516_s cn56xx; struct cvmx_pciercx_cfg516_s cn56xxp1; - struct cvmx_pciercx_cfg516_s cn63xx; - struct cvmx_pciercx_cfg516_s cn63xxp1; }; union cvmx_pciercx_cfg517 { @@ -1499,8 +1392,6 @@ union cvmx_pciercx_cfg517 { struct cvmx_pciercx_cfg517_s cn52xxp1; struct cvmx_pciercx_cfg517_s cn56xx; struct cvmx_pciercx_cfg517_s cn56xxp1; - struct cvmx_pciercx_cfg517_s cn63xx; - struct cvmx_pciercx_cfg517_s cn63xxp1; }; #endif diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-pescx-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-pescx-defs.h index aef84851a94c..f40cfaf84454 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-pescx-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-pescx-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,22 +28,38 @@ #ifndef __CVMX_PESCX_DEFS_H__ #define __CVMX_PESCX_DEFS_H__ -#define CVMX_PESCX_BIST_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000018ull) + ((block_id) & 1) * 0x8000000ull) -#define CVMX_PESCX_BIST_STATUS2(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000418ull) + ((block_id) & 1) * 0x8000000ull) -#define CVMX_PESCX_CFG_RD(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000030ull) + ((block_id) & 1) * 0x8000000ull) -#define CVMX_PESCX_CFG_WR(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000028ull) + ((block_id) & 1) * 0x8000000ull) -#define CVMX_PESCX_CPL_LUT_VALID(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000098ull) + ((block_id) & 1) * 0x8000000ull) -#define CVMX_PESCX_CTL_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000000ull) + ((block_id) & 1) * 0x8000000ull) -#define CVMX_PESCX_CTL_STATUS2(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000400ull) + ((block_id) & 1) * 0x8000000ull) -#define CVMX_PESCX_DBG_INFO(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000008ull) + ((block_id) & 1) * 0x8000000ull) -#define CVMX_PESCX_DBG_INFO_EN(block_id) (CVMX_ADD_IO_SEG(0x00011800C80000A0ull) + ((block_id) & 1) * 0x8000000ull) -#define CVMX_PESCX_DIAG_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000020ull) + ((block_id) & 1) * 0x8000000ull) -#define CVMX_PESCX_P2N_BAR0_START(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000080ull) + ((block_id) & 1) * 0x8000000ull) -#define CVMX_PESCX_P2N_BAR1_START(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000088ull) + ((block_id) & 1) * 0x8000000ull) -#define CVMX_PESCX_P2N_BAR2_START(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000090ull) + ((block_id) & 1) * 0x8000000ull) -#define CVMX_PESCX_P2P_BARX_END(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C8000048ull) + (((offset) & 3) + ((block_id) & 1) * 0x800000ull) * 16) -#define CVMX_PESCX_P2P_BARX_START(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C8000040ull) + (((offset) & 3) + ((block_id) & 1) * 0x800000ull) * 16) -#define CVMX_PESCX_TLP_CREDITS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000038ull) + ((block_id) & 1) * 0x8000000ull) +#define CVMX_PESCX_BIST_STATUS(block_id) \ + CVMX_ADD_IO_SEG(0x00011800C8000018ull + (((block_id) & 1) * 0x8000000ull)) +#define CVMX_PESCX_BIST_STATUS2(block_id) \ + CVMX_ADD_IO_SEG(0x00011800C8000418ull + (((block_id) & 1) * 0x8000000ull)) +#define CVMX_PESCX_CFG_RD(block_id) \ + CVMX_ADD_IO_SEG(0x00011800C8000030ull + (((block_id) & 1) * 0x8000000ull)) +#define CVMX_PESCX_CFG_WR(block_id) \ + CVMX_ADD_IO_SEG(0x00011800C8000028ull + (((block_id) & 1) * 0x8000000ull)) +#define CVMX_PESCX_CPL_LUT_VALID(block_id) \ + CVMX_ADD_IO_SEG(0x00011800C8000098ull + (((block_id) & 1) * 0x8000000ull)) +#define CVMX_PESCX_CTL_STATUS(block_id) \ + CVMX_ADD_IO_SEG(0x00011800C8000000ull + (((block_id) & 1) * 0x8000000ull)) +#define CVMX_PESCX_CTL_STATUS2(block_id) \ + CVMX_ADD_IO_SEG(0x00011800C8000400ull + (((block_id) & 1) * 0x8000000ull)) +#define CVMX_PESCX_DBG_INFO(block_id) \ + CVMX_ADD_IO_SEG(0x00011800C8000008ull + (((block_id) & 1) * 0x8000000ull)) +#define CVMX_PESCX_DBG_INFO_EN(block_id) \ + CVMX_ADD_IO_SEG(0x00011800C80000A0ull + (((block_id) & 1) * 0x8000000ull)) +#define CVMX_PESCX_DIAG_STATUS(block_id) \ + CVMX_ADD_IO_SEG(0x00011800C8000020ull + (((block_id) & 1) * 0x8000000ull)) +#define CVMX_PESCX_P2N_BAR0_START(block_id) \ + CVMX_ADD_IO_SEG(0x00011800C8000080ull + (((block_id) & 1) * 0x8000000ull)) +#define CVMX_PESCX_P2N_BAR1_START(block_id) \ + CVMX_ADD_IO_SEG(0x00011800C8000088ull + (((block_id) & 1) * 0x8000000ull)) +#define CVMX_PESCX_P2N_BAR2_START(block_id) \ + CVMX_ADD_IO_SEG(0x00011800C8000090ull + (((block_id) & 1) * 0x8000000ull)) +#define CVMX_PESCX_P2P_BARX_END(offset, block_id) \ + CVMX_ADD_IO_SEG(0x00011800C8000048ull + (((offset) & 3) * 16) + (((block_id) & 1) * 0x8000000ull)) +#define CVMX_PESCX_P2P_BARX_START(offset, block_id) \ + CVMX_ADD_IO_SEG(0x00011800C8000040ull + (((offset) & 3) * 16) + (((block_id) & 1) * 0x8000000ull)) +#define CVMX_PESCX_TLP_CREDITS(block_id) \ + CVMX_ADD_IO_SEG(0x00011800C8000038ull + (((block_id) & 1) * 0x8000000ull)) union cvmx_pescx_bist_status { uint64_t u64; diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-pexp-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-pexp-defs.h index 5ab8679d89af..5ea5dc571b54 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-pexp-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-pexp-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -35,191 +35,195 @@ #ifndef __CVMX_PEXP_DEFS_H__ #define __CVMX_PEXP_DEFS_H__ -#define CVMX_PEXP_NPEI_BAR1_INDEXX(offset) (CVMX_ADD_IO_SEG(0x00011F0000008000ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_NPEI_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011F0000008580ull)) -#define CVMX_PEXP_NPEI_BIST_STATUS2 (CVMX_ADD_IO_SEG(0x00011F0000008680ull)) -#define CVMX_PEXP_NPEI_CTL_PORT0 (CVMX_ADD_IO_SEG(0x00011F0000008250ull)) -#define CVMX_PEXP_NPEI_CTL_PORT1 (CVMX_ADD_IO_SEG(0x00011F0000008260ull)) -#define CVMX_PEXP_NPEI_CTL_STATUS (CVMX_ADD_IO_SEG(0x00011F0000008570ull)) -#define CVMX_PEXP_NPEI_CTL_STATUS2 (CVMX_ADD_IO_SEG(0x00011F000000BC00ull)) -#define CVMX_PEXP_NPEI_DATA_OUT_CNT (CVMX_ADD_IO_SEG(0x00011F00000085F0ull)) -#define CVMX_PEXP_NPEI_DBG_DATA (CVMX_ADD_IO_SEG(0x00011F0000008510ull)) -#define CVMX_PEXP_NPEI_DBG_SELECT (CVMX_ADD_IO_SEG(0x00011F0000008500ull)) -#define CVMX_PEXP_NPEI_DMA0_INT_LEVEL (CVMX_ADD_IO_SEG(0x00011F00000085C0ull)) -#define CVMX_PEXP_NPEI_DMA1_INT_LEVEL (CVMX_ADD_IO_SEG(0x00011F00000085D0ull)) -#define CVMX_PEXP_NPEI_DMAX_COUNTS(offset) (CVMX_ADD_IO_SEG(0x00011F0000008450ull) + ((offset) & 7) * 16) -#define CVMX_PEXP_NPEI_DMAX_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F00000083B0ull) + ((offset) & 7) * 16) -#define CVMX_PEXP_NPEI_DMAX_IBUFF_SADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000008400ull) + ((offset) & 7) * 16) -#define CVMX_PEXP_NPEI_DMAX_NADDR(offset) (CVMX_ADD_IO_SEG(0x00011F00000084A0ull) + ((offset) & 7) * 16) -#define CVMX_PEXP_NPEI_DMA_CNTS (CVMX_ADD_IO_SEG(0x00011F00000085E0ull)) -#define CVMX_PEXP_NPEI_DMA_CONTROL (CVMX_ADD_IO_SEG(0x00011F00000083A0ull)) -#define CVMX_PEXP_NPEI_DMA_PCIE_REQ_NUM (CVMX_ADD_IO_SEG(0x00011F00000085B0ull)) -#define CVMX_PEXP_NPEI_DMA_STATE1 (CVMX_ADD_IO_SEG(0x00011F00000086C0ull)) -#define CVMX_PEXP_NPEI_DMA_STATE1_P1 (CVMX_ADD_IO_SEG(0x00011F0000008680ull)) -#define CVMX_PEXP_NPEI_DMA_STATE2 (CVMX_ADD_IO_SEG(0x00011F00000086D0ull)) -#define CVMX_PEXP_NPEI_DMA_STATE2_P1 (CVMX_ADD_IO_SEG(0x00011F0000008690ull)) -#define CVMX_PEXP_NPEI_DMA_STATE3_P1 (CVMX_ADD_IO_SEG(0x00011F00000086A0ull)) -#define CVMX_PEXP_NPEI_DMA_STATE4_P1 (CVMX_ADD_IO_SEG(0x00011F00000086B0ull)) -#define CVMX_PEXP_NPEI_DMA_STATE5_P1 (CVMX_ADD_IO_SEG(0x00011F00000086C0ull)) -#define CVMX_PEXP_NPEI_INT_A_ENB (CVMX_ADD_IO_SEG(0x00011F0000008560ull)) -#define CVMX_PEXP_NPEI_INT_A_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BCE0ull)) -#define CVMX_PEXP_NPEI_INT_A_SUM (CVMX_ADD_IO_SEG(0x00011F0000008550ull)) -#define CVMX_PEXP_NPEI_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000008540ull)) -#define CVMX_PEXP_NPEI_INT_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BCD0ull)) -#define CVMX_PEXP_NPEI_INT_INFO (CVMX_ADD_IO_SEG(0x00011F0000008590ull)) -#define CVMX_PEXP_NPEI_INT_SUM (CVMX_ADD_IO_SEG(0x00011F0000008530ull)) -#define CVMX_PEXP_NPEI_INT_SUM2 (CVMX_ADD_IO_SEG(0x00011F000000BCC0ull)) -#define CVMX_PEXP_NPEI_LAST_WIN_RDATA0 (CVMX_ADD_IO_SEG(0x00011F0000008600ull)) -#define CVMX_PEXP_NPEI_LAST_WIN_RDATA1 (CVMX_ADD_IO_SEG(0x00011F0000008610ull)) -#define CVMX_PEXP_NPEI_MEM_ACCESS_CTL (CVMX_ADD_IO_SEG(0x00011F00000084F0ull)) -#define CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(offset) (CVMX_ADD_IO_SEG(0x00011F0000008280ull) + ((offset) & 31) * 16 - 16*12) -#define CVMX_PEXP_NPEI_MSI_ENB0 (CVMX_ADD_IO_SEG(0x00011F000000BC50ull)) -#define CVMX_PEXP_NPEI_MSI_ENB1 (CVMX_ADD_IO_SEG(0x00011F000000BC60ull)) -#define CVMX_PEXP_NPEI_MSI_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BC70ull)) -#define CVMX_PEXP_NPEI_MSI_ENB3 (CVMX_ADD_IO_SEG(0x00011F000000BC80ull)) -#define CVMX_PEXP_NPEI_MSI_RCV0 (CVMX_ADD_IO_SEG(0x00011F000000BC10ull)) -#define CVMX_PEXP_NPEI_MSI_RCV1 (CVMX_ADD_IO_SEG(0x00011F000000BC20ull)) -#define CVMX_PEXP_NPEI_MSI_RCV2 (CVMX_ADD_IO_SEG(0x00011F000000BC30ull)) -#define CVMX_PEXP_NPEI_MSI_RCV3 (CVMX_ADD_IO_SEG(0x00011F000000BC40ull)) -#define CVMX_PEXP_NPEI_MSI_RD_MAP (CVMX_ADD_IO_SEG(0x00011F000000BCA0ull)) -#define CVMX_PEXP_NPEI_MSI_W1C_ENB0 (CVMX_ADD_IO_SEG(0x00011F000000BCF0ull)) -#define CVMX_PEXP_NPEI_MSI_W1C_ENB1 (CVMX_ADD_IO_SEG(0x00011F000000BD00ull)) -#define CVMX_PEXP_NPEI_MSI_W1C_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BD10ull)) -#define CVMX_PEXP_NPEI_MSI_W1C_ENB3 (CVMX_ADD_IO_SEG(0x00011F000000BD20ull)) -#define CVMX_PEXP_NPEI_MSI_W1S_ENB0 (CVMX_ADD_IO_SEG(0x00011F000000BD30ull)) -#define CVMX_PEXP_NPEI_MSI_W1S_ENB1 (CVMX_ADD_IO_SEG(0x00011F000000BD40ull)) -#define CVMX_PEXP_NPEI_MSI_W1S_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BD50ull)) -#define CVMX_PEXP_NPEI_MSI_W1S_ENB3 (CVMX_ADD_IO_SEG(0x00011F000000BD60ull)) -#define CVMX_PEXP_NPEI_MSI_WR_MAP (CVMX_ADD_IO_SEG(0x00011F000000BC90ull)) -#define CVMX_PEXP_NPEI_PCIE_CREDIT_CNT (CVMX_ADD_IO_SEG(0x00011F000000BD70ull)) -#define CVMX_PEXP_NPEI_PCIE_MSI_RCV (CVMX_ADD_IO_SEG(0x00011F000000BCB0ull)) -#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B1 (CVMX_ADD_IO_SEG(0x00011F0000008650ull)) -#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B2 (CVMX_ADD_IO_SEG(0x00011F0000008660ull)) -#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B3 (CVMX_ADD_IO_SEG(0x00011F0000008670ull)) -#define CVMX_PEXP_NPEI_PKTX_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F000000A400ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_NPEI_PKTX_INSTR_BADDR(offset) (CVMX_ADD_IO_SEG(0x00011F000000A800ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F000000AC00ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) (CVMX_ADD_IO_SEG(0x00011F000000B000ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_NPEI_PKTX_INSTR_HEADER(offset) (CVMX_ADD_IO_SEG(0x00011F000000B400ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_NPEI_PKTX_IN_BP(offset) (CVMX_ADD_IO_SEG(0x00011F000000B800ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_NPEI_PKTX_SLIST_BADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000009400ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F0000009800ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) (CVMX_ADD_IO_SEG(0x00011F0000009C00ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_NPEI_PKT_CNT_INT (CVMX_ADD_IO_SEG(0x00011F0000009110ull)) -#define CVMX_PEXP_NPEI_PKT_CNT_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000009130ull)) -#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ES (CVMX_ADD_IO_SEG(0x00011F00000090B0ull)) -#define CVMX_PEXP_NPEI_PKT_DATA_OUT_NS (CVMX_ADD_IO_SEG(0x00011F00000090A0ull)) -#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ROR (CVMX_ADD_IO_SEG(0x00011F0000009090ull)) -#define CVMX_PEXP_NPEI_PKT_DPADDR (CVMX_ADD_IO_SEG(0x00011F0000009080ull)) -#define CVMX_PEXP_NPEI_PKT_INPUT_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000009150ull)) -#define CVMX_PEXP_NPEI_PKT_INSTR_ENB (CVMX_ADD_IO_SEG(0x00011F0000009000ull)) -#define CVMX_PEXP_NPEI_PKT_INSTR_RD_SIZE (CVMX_ADD_IO_SEG(0x00011F0000009190ull)) -#define CVMX_PEXP_NPEI_PKT_INSTR_SIZE (CVMX_ADD_IO_SEG(0x00011F0000009020ull)) -#define CVMX_PEXP_NPEI_PKT_INT_LEVELS (CVMX_ADD_IO_SEG(0x00011F0000009100ull)) -#define CVMX_PEXP_NPEI_PKT_IN_BP (CVMX_ADD_IO_SEG(0x00011F00000086B0ull)) -#define CVMX_PEXP_NPEI_PKT_IN_DONEX_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F000000A000ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_NPEI_PKT_IN_INSTR_COUNTS (CVMX_ADD_IO_SEG(0x00011F00000086A0ull)) -#define CVMX_PEXP_NPEI_PKT_IN_PCIE_PORT (CVMX_ADD_IO_SEG(0x00011F00000091A0ull)) -#define CVMX_PEXP_NPEI_PKT_IPTR (CVMX_ADD_IO_SEG(0x00011F0000009070ull)) -#define CVMX_PEXP_NPEI_PKT_OUTPUT_WMARK (CVMX_ADD_IO_SEG(0x00011F0000009160ull)) -#define CVMX_PEXP_NPEI_PKT_OUT_BMODE (CVMX_ADD_IO_SEG(0x00011F00000090D0ull)) -#define CVMX_PEXP_NPEI_PKT_OUT_ENB (CVMX_ADD_IO_SEG(0x00011F0000009010ull)) -#define CVMX_PEXP_NPEI_PKT_PCIE_PORT (CVMX_ADD_IO_SEG(0x00011F00000090E0ull)) -#define CVMX_PEXP_NPEI_PKT_PORT_IN_RST (CVMX_ADD_IO_SEG(0x00011F0000008690ull)) -#define CVMX_PEXP_NPEI_PKT_SLIST_ES (CVMX_ADD_IO_SEG(0x00011F0000009050ull)) -#define CVMX_PEXP_NPEI_PKT_SLIST_ID_SIZE (CVMX_ADD_IO_SEG(0x00011F0000009180ull)) -#define CVMX_PEXP_NPEI_PKT_SLIST_NS (CVMX_ADD_IO_SEG(0x00011F0000009040ull)) -#define CVMX_PEXP_NPEI_PKT_SLIST_ROR (CVMX_ADD_IO_SEG(0x00011F0000009030ull)) -#define CVMX_PEXP_NPEI_PKT_TIME_INT (CVMX_ADD_IO_SEG(0x00011F0000009120ull)) -#define CVMX_PEXP_NPEI_PKT_TIME_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000009140ull)) -#define CVMX_PEXP_NPEI_RSL_INT_BLOCKS (CVMX_ADD_IO_SEG(0x00011F0000008520ull)) -#define CVMX_PEXP_NPEI_SCRATCH_1 (CVMX_ADD_IO_SEG(0x00011F0000008270ull)) -#define CVMX_PEXP_NPEI_STATE1 (CVMX_ADD_IO_SEG(0x00011F0000008620ull)) -#define CVMX_PEXP_NPEI_STATE2 (CVMX_ADD_IO_SEG(0x00011F0000008630ull)) -#define CVMX_PEXP_NPEI_STATE3 (CVMX_ADD_IO_SEG(0x00011F0000008640ull)) -#define CVMX_PEXP_NPEI_WINDOW_CTL (CVMX_ADD_IO_SEG(0x00011F0000008380ull)) -#define CVMX_PEXP_SLI_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011F0000010580ull)) -#define CVMX_PEXP_SLI_CTL_PORTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000010050ull) + ((offset) & 1) * 16) -#define CVMX_PEXP_SLI_CTL_STATUS (CVMX_ADD_IO_SEG(0x00011F0000010570ull)) -#define CVMX_PEXP_SLI_DATA_OUT_CNT (CVMX_ADD_IO_SEG(0x00011F00000105F0ull)) -#define CVMX_PEXP_SLI_DBG_DATA (CVMX_ADD_IO_SEG(0x00011F0000010310ull)) -#define CVMX_PEXP_SLI_DBG_SELECT (CVMX_ADD_IO_SEG(0x00011F0000010300ull)) -#define CVMX_PEXP_SLI_DMAX_CNT(offset) (CVMX_ADD_IO_SEG(0x00011F0000010400ull) + ((offset) & 1) * 16) -#define CVMX_PEXP_SLI_DMAX_INT_LEVEL(offset) (CVMX_ADD_IO_SEG(0x00011F00000103E0ull) + ((offset) & 1) * 16) -#define CVMX_PEXP_SLI_DMAX_TIM(offset) (CVMX_ADD_IO_SEG(0x00011F0000010420ull) + ((offset) & 1) * 16) -#define CVMX_PEXP_SLI_INT_ENB_CIU (CVMX_ADD_IO_SEG(0x00011F0000013CD0ull)) -#define CVMX_PEXP_SLI_INT_ENB_PORTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000010340ull) + ((offset) & 1) * 16) -#define CVMX_PEXP_SLI_INT_SUM (CVMX_ADD_IO_SEG(0x00011F0000010330ull)) -#define CVMX_PEXP_SLI_LAST_WIN_RDATA0 (CVMX_ADD_IO_SEG(0x00011F0000010600ull)) -#define CVMX_PEXP_SLI_LAST_WIN_RDATA1 (CVMX_ADD_IO_SEG(0x00011F0000010610ull)) -#define CVMX_PEXP_SLI_MAC_CREDIT_CNT (CVMX_ADD_IO_SEG(0x00011F0000013D70ull)) -#define CVMX_PEXP_SLI_MEM_ACCESS_CTL (CVMX_ADD_IO_SEG(0x00011F00000102F0ull)) -#define CVMX_PEXP_SLI_MEM_ACCESS_SUBIDX(offset) (CVMX_ADD_IO_SEG(0x00011F00000100E0ull) + ((offset) & 31) * 16 - 16*12) -#define CVMX_PEXP_SLI_MSI_ENB0 (CVMX_ADD_IO_SEG(0x00011F0000013C50ull)) -#define CVMX_PEXP_SLI_MSI_ENB1 (CVMX_ADD_IO_SEG(0x00011F0000013C60ull)) -#define CVMX_PEXP_SLI_MSI_ENB2 (CVMX_ADD_IO_SEG(0x00011F0000013C70ull)) -#define CVMX_PEXP_SLI_MSI_ENB3 (CVMX_ADD_IO_SEG(0x00011F0000013C80ull)) -#define CVMX_PEXP_SLI_MSI_RCV0 (CVMX_ADD_IO_SEG(0x00011F0000013C10ull)) -#define CVMX_PEXP_SLI_MSI_RCV1 (CVMX_ADD_IO_SEG(0x00011F0000013C20ull)) -#define CVMX_PEXP_SLI_MSI_RCV2 (CVMX_ADD_IO_SEG(0x00011F0000013C30ull)) -#define CVMX_PEXP_SLI_MSI_RCV3 (CVMX_ADD_IO_SEG(0x00011F0000013C40ull)) -#define CVMX_PEXP_SLI_MSI_RD_MAP (CVMX_ADD_IO_SEG(0x00011F0000013CA0ull)) -#define CVMX_PEXP_SLI_MSI_W1C_ENB0 (CVMX_ADD_IO_SEG(0x00011F0000013CF0ull)) -#define CVMX_PEXP_SLI_MSI_W1C_ENB1 (CVMX_ADD_IO_SEG(0x00011F0000013D00ull)) -#define CVMX_PEXP_SLI_MSI_W1C_ENB2 (CVMX_ADD_IO_SEG(0x00011F0000013D10ull)) -#define CVMX_PEXP_SLI_MSI_W1C_ENB3 (CVMX_ADD_IO_SEG(0x00011F0000013D20ull)) -#define CVMX_PEXP_SLI_MSI_W1S_ENB0 (CVMX_ADD_IO_SEG(0x00011F0000013D30ull)) -#define CVMX_PEXP_SLI_MSI_W1S_ENB1 (CVMX_ADD_IO_SEG(0x00011F0000013D40ull)) -#define CVMX_PEXP_SLI_MSI_W1S_ENB2 (CVMX_ADD_IO_SEG(0x00011F0000013D50ull)) -#define CVMX_PEXP_SLI_MSI_W1S_ENB3 (CVMX_ADD_IO_SEG(0x00011F0000013D60ull)) -#define CVMX_PEXP_SLI_MSI_WR_MAP (CVMX_ADD_IO_SEG(0x00011F0000013C90ull)) -#define CVMX_PEXP_SLI_PCIE_MSI_RCV (CVMX_ADD_IO_SEG(0x00011F0000013CB0ull)) -#define CVMX_PEXP_SLI_PCIE_MSI_RCV_B1 (CVMX_ADD_IO_SEG(0x00011F0000010650ull)) -#define CVMX_PEXP_SLI_PCIE_MSI_RCV_B2 (CVMX_ADD_IO_SEG(0x00011F0000010660ull)) -#define CVMX_PEXP_SLI_PCIE_MSI_RCV_B3 (CVMX_ADD_IO_SEG(0x00011F0000010670ull)) -#define CVMX_PEXP_SLI_PKTX_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F0000012400ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_SLI_PKTX_INSTR_BADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000012800ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_SLI_PKTX_INSTR_BAOFF_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F0000012C00ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_SLI_PKTX_INSTR_FIFO_RSIZE(offset) (CVMX_ADD_IO_SEG(0x00011F0000013000ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_SLI_PKTX_INSTR_HEADER(offset) (CVMX_ADD_IO_SEG(0x00011F0000013400ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_SLI_PKTX_IN_BP(offset) (CVMX_ADD_IO_SEG(0x00011F0000013800ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_SLI_PKTX_OUT_SIZE(offset) (CVMX_ADD_IO_SEG(0x00011F0000010C00ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_SLI_PKTX_SLIST_BADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000011400ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_SLI_PKTX_SLIST_BAOFF_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F0000011800ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_SLI_PKTX_SLIST_FIFO_RSIZE(offset) (CVMX_ADD_IO_SEG(0x00011F0000011C00ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_SLI_PKT_CNT_INT (CVMX_ADD_IO_SEG(0x00011F0000011130ull)) -#define CVMX_PEXP_SLI_PKT_CNT_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000011150ull)) -#define CVMX_PEXP_SLI_PKT_CTL (CVMX_ADD_IO_SEG(0x00011F0000011220ull)) -#define CVMX_PEXP_SLI_PKT_DATA_OUT_ES (CVMX_ADD_IO_SEG(0x00011F00000110B0ull)) -#define CVMX_PEXP_SLI_PKT_DATA_OUT_NS (CVMX_ADD_IO_SEG(0x00011F00000110A0ull)) -#define CVMX_PEXP_SLI_PKT_DATA_OUT_ROR (CVMX_ADD_IO_SEG(0x00011F0000011090ull)) -#define CVMX_PEXP_SLI_PKT_DPADDR (CVMX_ADD_IO_SEG(0x00011F0000011080ull)) -#define CVMX_PEXP_SLI_PKT_INPUT_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000011170ull)) -#define CVMX_PEXP_SLI_PKT_INSTR_ENB (CVMX_ADD_IO_SEG(0x00011F0000011000ull)) -#define CVMX_PEXP_SLI_PKT_INSTR_RD_SIZE (CVMX_ADD_IO_SEG(0x00011F00000111A0ull)) -#define CVMX_PEXP_SLI_PKT_INSTR_SIZE (CVMX_ADD_IO_SEG(0x00011F0000011020ull)) -#define CVMX_PEXP_SLI_PKT_INT_LEVELS (CVMX_ADD_IO_SEG(0x00011F0000011120ull)) -#define CVMX_PEXP_SLI_PKT_IN_BP (CVMX_ADD_IO_SEG(0x00011F0000011210ull)) -#define CVMX_PEXP_SLI_PKT_IN_DONEX_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F0000012000ull) + ((offset) & 31) * 16) -#define CVMX_PEXP_SLI_PKT_IN_INSTR_COUNTS (CVMX_ADD_IO_SEG(0x00011F0000011200ull)) -#define CVMX_PEXP_SLI_PKT_IN_PCIE_PORT (CVMX_ADD_IO_SEG(0x00011F00000111B0ull)) -#define CVMX_PEXP_SLI_PKT_IPTR (CVMX_ADD_IO_SEG(0x00011F0000011070ull)) -#define CVMX_PEXP_SLI_PKT_OUTPUT_WMARK (CVMX_ADD_IO_SEG(0x00011F0000011180ull)) -#define CVMX_PEXP_SLI_PKT_OUT_BMODE (CVMX_ADD_IO_SEG(0x00011F00000110D0ull)) -#define CVMX_PEXP_SLI_PKT_OUT_ENB (CVMX_ADD_IO_SEG(0x00011F0000011010ull)) -#define CVMX_PEXP_SLI_PKT_PCIE_PORT (CVMX_ADD_IO_SEG(0x00011F00000110E0ull)) -#define CVMX_PEXP_SLI_PKT_PORT_IN_RST (CVMX_ADD_IO_SEG(0x00011F00000111F0ull)) -#define CVMX_PEXP_SLI_PKT_SLIST_ES (CVMX_ADD_IO_SEG(0x00011F0000011050ull)) -#define CVMX_PEXP_SLI_PKT_SLIST_NS (CVMX_ADD_IO_SEG(0x00011F0000011040ull)) -#define CVMX_PEXP_SLI_PKT_SLIST_ROR (CVMX_ADD_IO_SEG(0x00011F0000011030ull)) -#define CVMX_PEXP_SLI_PKT_TIME_INT (CVMX_ADD_IO_SEG(0x00011F0000011140ull)) -#define CVMX_PEXP_SLI_PKT_TIME_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000011160ull)) -#define CVMX_PEXP_SLI_S2M_PORTX_CTL(offset) (CVMX_ADD_IO_SEG(0x00011F0000013D80ull) + ((offset) & 1) * 16) -#define CVMX_PEXP_SLI_SCRATCH_1 (CVMX_ADD_IO_SEG(0x00011F00000103C0ull)) -#define CVMX_PEXP_SLI_SCRATCH_2 (CVMX_ADD_IO_SEG(0x00011F00000103D0ull)) -#define CVMX_PEXP_SLI_STATE1 (CVMX_ADD_IO_SEG(0x00011F0000010620ull)) -#define CVMX_PEXP_SLI_STATE2 (CVMX_ADD_IO_SEG(0x00011F0000010630ull)) -#define CVMX_PEXP_SLI_STATE3 (CVMX_ADD_IO_SEG(0x00011F0000010640ull)) -#define CVMX_PEXP_SLI_WINDOW_CTL (CVMX_ADD_IO_SEG(0x00011F00000102E0ull)) +#define CVMX_PEXP_NPEI_BAR1_INDEXX(offset) \ + CVMX_ADD_IO_SEG(0x00011F0000008000ull + (((offset) & 31) * 16)) +#define CVMX_PEXP_NPEI_BIST_STATUS \ + CVMX_ADD_IO_SEG(0x00011F0000008580ull) +#define CVMX_PEXP_NPEI_BIST_STATUS2 \ + CVMX_ADD_IO_SEG(0x00011F0000008680ull) +#define CVMX_PEXP_NPEI_CTL_PORT0 \ + CVMX_ADD_IO_SEG(0x00011F0000008250ull) +#define CVMX_PEXP_NPEI_CTL_PORT1 \ + CVMX_ADD_IO_SEG(0x00011F0000008260ull) +#define CVMX_PEXP_NPEI_CTL_STATUS \ + CVMX_ADD_IO_SEG(0x00011F0000008570ull) +#define CVMX_PEXP_NPEI_CTL_STATUS2 \ + CVMX_ADD_IO_SEG(0x00011F000000BC00ull) +#define CVMX_PEXP_NPEI_DATA_OUT_CNT \ + CVMX_ADD_IO_SEG(0x00011F00000085F0ull) +#define CVMX_PEXP_NPEI_DBG_DATA \ + CVMX_ADD_IO_SEG(0x00011F0000008510ull) +#define CVMX_PEXP_NPEI_DBG_SELECT \ + CVMX_ADD_IO_SEG(0x00011F0000008500ull) +#define CVMX_PEXP_NPEI_DMA0_INT_LEVEL \ + CVMX_ADD_IO_SEG(0x00011F00000085C0ull) +#define CVMX_PEXP_NPEI_DMA1_INT_LEVEL \ + CVMX_ADD_IO_SEG(0x00011F00000085D0ull) +#define CVMX_PEXP_NPEI_DMAX_COUNTS(offset) \ + CVMX_ADD_IO_SEG(0x00011F0000008450ull + (((offset) & 7) * 16)) +#define CVMX_PEXP_NPEI_DMAX_DBELL(offset) \ + CVMX_ADD_IO_SEG(0x00011F00000083B0ull + (((offset) & 7) * 16)) +#define CVMX_PEXP_NPEI_DMAX_IBUFF_SADDR(offset) \ + CVMX_ADD_IO_SEG(0x00011F0000008400ull + (((offset) & 7) * 16)) +#define CVMX_PEXP_NPEI_DMAX_NADDR(offset) \ + CVMX_ADD_IO_SEG(0x00011F00000084A0ull + (((offset) & 7) * 16)) +#define CVMX_PEXP_NPEI_DMA_CNTS \ + CVMX_ADD_IO_SEG(0x00011F00000085E0ull) +#define CVMX_PEXP_NPEI_DMA_CONTROL \ + CVMX_ADD_IO_SEG(0x00011F00000083A0ull) +#define CVMX_PEXP_NPEI_INT_A_ENB \ + CVMX_ADD_IO_SEG(0x00011F0000008560ull) +#define CVMX_PEXP_NPEI_INT_A_ENB2 \ + CVMX_ADD_IO_SEG(0x00011F000000BCE0ull) +#define CVMX_PEXP_NPEI_INT_A_SUM \ + CVMX_ADD_IO_SEG(0x00011F0000008550ull) +#define CVMX_PEXP_NPEI_INT_ENB \ + CVMX_ADD_IO_SEG(0x00011F0000008540ull) +#define CVMX_PEXP_NPEI_INT_ENB2 \ + CVMX_ADD_IO_SEG(0x00011F000000BCD0ull) +#define CVMX_PEXP_NPEI_INT_INFO \ + CVMX_ADD_IO_SEG(0x00011F0000008590ull) +#define CVMX_PEXP_NPEI_INT_SUM \ + CVMX_ADD_IO_SEG(0x00011F0000008530ull) +#define CVMX_PEXP_NPEI_INT_SUM2 \ + CVMX_ADD_IO_SEG(0x00011F000000BCC0ull) +#define CVMX_PEXP_NPEI_LAST_WIN_RDATA0 \ + CVMX_ADD_IO_SEG(0x00011F0000008600ull) +#define CVMX_PEXP_NPEI_LAST_WIN_RDATA1 \ + CVMX_ADD_IO_SEG(0x00011F0000008610ull) +#define CVMX_PEXP_NPEI_MEM_ACCESS_CTL \ + CVMX_ADD_IO_SEG(0x00011F00000084F0ull) +#define CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(offset) \ + CVMX_ADD_IO_SEG(0x00011F0000008280ull + (((offset) & 31) * 16) - 16 * 12) +#define CVMX_PEXP_NPEI_MSI_ENB0 \ + CVMX_ADD_IO_SEG(0x00011F000000BC50ull) +#define CVMX_PEXP_NPEI_MSI_ENB1 \ + CVMX_ADD_IO_SEG(0x00011F000000BC60ull) +#define CVMX_PEXP_NPEI_MSI_ENB2 \ + CVMX_ADD_IO_SEG(0x00011F000000BC70ull) +#define CVMX_PEXP_NPEI_MSI_ENB3 \ + CVMX_ADD_IO_SEG(0x00011F000000BC80ull) +#define CVMX_PEXP_NPEI_MSI_RCV0 \ + CVMX_ADD_IO_SEG(0x00011F000000BC10ull) +#define CVMX_PEXP_NPEI_MSI_RCV1 \ + CVMX_ADD_IO_SEG(0x00011F000000BC20ull) +#define CVMX_PEXP_NPEI_MSI_RCV2 \ + CVMX_ADD_IO_SEG(0x00011F000000BC30ull) +#define CVMX_PEXP_NPEI_MSI_RCV3 \ + CVMX_ADD_IO_SEG(0x00011F000000BC40ull) +#define CVMX_PEXP_NPEI_MSI_RD_MAP \ + CVMX_ADD_IO_SEG(0x00011F000000BCA0ull) +#define CVMX_PEXP_NPEI_MSI_W1C_ENB0 \ + CVMX_ADD_IO_SEG(0x00011F000000BCF0ull) +#define CVMX_PEXP_NPEI_MSI_W1C_ENB1 \ + CVMX_ADD_IO_SEG(0x00011F000000BD00ull) +#define CVMX_PEXP_NPEI_MSI_W1C_ENB2 \ + CVMX_ADD_IO_SEG(0x00011F000000BD10ull) +#define CVMX_PEXP_NPEI_MSI_W1C_ENB3 \ + CVMX_ADD_IO_SEG(0x00011F000000BD20ull) +#define CVMX_PEXP_NPEI_MSI_W1S_ENB0 \ + CVMX_ADD_IO_SEG(0x00011F000000BD30ull) +#define CVMX_PEXP_NPEI_MSI_W1S_ENB1 \ + CVMX_ADD_IO_SEG(0x00011F000000BD40ull) +#define CVMX_PEXP_NPEI_MSI_W1S_ENB2 \ + CVMX_ADD_IO_SEG(0x00011F000000BD50ull) +#define CVMX_PEXP_NPEI_MSI_W1S_ENB3 \ + CVMX_ADD_IO_SEG(0x00011F000000BD60ull) +#define CVMX_PEXP_NPEI_MSI_WR_MAP \ + CVMX_ADD_IO_SEG(0x00011F000000BC90ull) +#define CVMX_PEXP_NPEI_PCIE_CREDIT_CNT \ + CVMX_ADD_IO_SEG(0x00011F000000BD70ull) +#define CVMX_PEXP_NPEI_PCIE_MSI_RCV \ + CVMX_ADD_IO_SEG(0x00011F000000BCB0ull) +#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B1 \ + CVMX_ADD_IO_SEG(0x00011F0000008650ull) +#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B2 \ + CVMX_ADD_IO_SEG(0x00011F0000008660ull) +#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B3 \ + CVMX_ADD_IO_SEG(0x00011F0000008670ull) +#define CVMX_PEXP_NPEI_PKTX_CNTS(offset) \ + CVMX_ADD_IO_SEG(0x00011F000000A400ull + (((offset) & 31) * 16)) +#define CVMX_PEXP_NPEI_PKTX_INSTR_BADDR(offset) \ + CVMX_ADD_IO_SEG(0x00011F000000A800ull + (((offset) & 31) * 16)) +#define CVMX_PEXP_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) \ + CVMX_ADD_IO_SEG(0x00011F000000AC00ull + (((offset) & 31) * 16)) +#define CVMX_PEXP_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) \ + CVMX_ADD_IO_SEG(0x00011F000000B000ull + (((offset) & 31) * 16)) +#define CVMX_PEXP_NPEI_PKTX_INSTR_HEADER(offset) \ + CVMX_ADD_IO_SEG(0x00011F000000B400ull + (((offset) & 31) * 16)) +#define CVMX_PEXP_NPEI_PKTX_IN_BP(offset) \ + CVMX_ADD_IO_SEG(0x00011F000000B800ull + (((offset) & 31) * 16)) +#define CVMX_PEXP_NPEI_PKTX_SLIST_BADDR(offset) \ + CVMX_ADD_IO_SEG(0x00011F0000009400ull + (((offset) & 31) * 16)) +#define CVMX_PEXP_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) \ + CVMX_ADD_IO_SEG(0x00011F0000009800ull + (((offset) & 31) * 16)) +#define CVMX_PEXP_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) \ + CVMX_ADD_IO_SEG(0x00011F0000009C00ull + (((offset) & 31) * 16)) +#define CVMX_PEXP_NPEI_PKT_CNT_INT \ + CVMX_ADD_IO_SEG(0x00011F0000009110ull) +#define CVMX_PEXP_NPEI_PKT_CNT_INT_ENB \ + CVMX_ADD_IO_SEG(0x00011F0000009130ull) +#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ES \ + CVMX_ADD_IO_SEG(0x00011F00000090B0ull) +#define CVMX_PEXP_NPEI_PKT_DATA_OUT_NS \ + CVMX_ADD_IO_SEG(0x00011F00000090A0ull) +#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ROR \ + CVMX_ADD_IO_SEG(0x00011F0000009090ull) +#define CVMX_PEXP_NPEI_PKT_DPADDR \ + CVMX_ADD_IO_SEG(0x00011F0000009080ull) +#define CVMX_PEXP_NPEI_PKT_INPUT_CONTROL \ + CVMX_ADD_IO_SEG(0x00011F0000009150ull) +#define CVMX_PEXP_NPEI_PKT_INSTR_ENB \ + CVMX_ADD_IO_SEG(0x00011F0000009000ull) +#define CVMX_PEXP_NPEI_PKT_INSTR_RD_SIZE \ + CVMX_ADD_IO_SEG(0x00011F0000009190ull) +#define CVMX_PEXP_NPEI_PKT_INSTR_SIZE \ + CVMX_ADD_IO_SEG(0x00011F0000009020ull) +#define CVMX_PEXP_NPEI_PKT_INT_LEVELS \ + CVMX_ADD_IO_SEG(0x00011F0000009100ull) +#define CVMX_PEXP_NPEI_PKT_IN_BP \ + CVMX_ADD_IO_SEG(0x00011F00000086B0ull) +#define CVMX_PEXP_NPEI_PKT_IN_DONEX_CNTS(offset) \ + CVMX_ADD_IO_SEG(0x00011F000000A000ull + (((offset) & 31) * 16)) +#define CVMX_PEXP_NPEI_PKT_IN_INSTR_COUNTS \ + CVMX_ADD_IO_SEG(0x00011F00000086A0ull) +#define CVMX_PEXP_NPEI_PKT_IN_PCIE_PORT \ + CVMX_ADD_IO_SEG(0x00011F00000091A0ull) +#define CVMX_PEXP_NPEI_PKT_IPTR \ + CVMX_ADD_IO_SEG(0x00011F0000009070ull) +#define CVMX_PEXP_NPEI_PKT_OUTPUT_WMARK \ + CVMX_ADD_IO_SEG(0x00011F0000009160ull) +#define CVMX_PEXP_NPEI_PKT_OUT_BMODE \ + CVMX_ADD_IO_SEG(0x00011F00000090D0ull) +#define CVMX_PEXP_NPEI_PKT_OUT_ENB \ + CVMX_ADD_IO_SEG(0x00011F0000009010ull) +#define CVMX_PEXP_NPEI_PKT_PCIE_PORT \ + CVMX_ADD_IO_SEG(0x00011F00000090E0ull) +#define CVMX_PEXP_NPEI_PKT_PORT_IN_RST \ + CVMX_ADD_IO_SEG(0x00011F0000008690ull) +#define CVMX_PEXP_NPEI_PKT_SLIST_ES \ + CVMX_ADD_IO_SEG(0x00011F0000009050ull) +#define CVMX_PEXP_NPEI_PKT_SLIST_ID_SIZE \ + CVMX_ADD_IO_SEG(0x00011F0000009180ull) +#define CVMX_PEXP_NPEI_PKT_SLIST_NS \ + CVMX_ADD_IO_SEG(0x00011F0000009040ull) +#define CVMX_PEXP_NPEI_PKT_SLIST_ROR \ + CVMX_ADD_IO_SEG(0x00011F0000009030ull) +#define CVMX_PEXP_NPEI_PKT_TIME_INT \ + CVMX_ADD_IO_SEG(0x00011F0000009120ull) +#define CVMX_PEXP_NPEI_PKT_TIME_INT_ENB \ + CVMX_ADD_IO_SEG(0x00011F0000009140ull) +#define CVMX_PEXP_NPEI_RSL_INT_BLOCKS \ + CVMX_ADD_IO_SEG(0x00011F0000008520ull) +#define CVMX_PEXP_NPEI_SCRATCH_1 \ + CVMX_ADD_IO_SEG(0x00011F0000008270ull) +#define CVMX_PEXP_NPEI_STATE1 \ + CVMX_ADD_IO_SEG(0x00011F0000008620ull) +#define CVMX_PEXP_NPEI_STATE2 \ + CVMX_ADD_IO_SEG(0x00011F0000008630ull) +#define CVMX_PEXP_NPEI_STATE3 \ + CVMX_ADD_IO_SEG(0x00011F0000008640ull) +#define CVMX_PEXP_NPEI_WINDOW_CTL \ + CVMX_ADD_IO_SEG(0x00011F0000008380ull) #endif diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-pow-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-pow-defs.h index 39fd75b03f77..2d82e24be51c 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-pow-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-pow-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,29 +28,52 @@ #ifndef __CVMX_POW_DEFS_H__ #define __CVMX_POW_DEFS_H__ -#define CVMX_POW_BIST_STAT (CVMX_ADD_IO_SEG(0x00016700000003F8ull)) -#define CVMX_POW_DS_PC (CVMX_ADD_IO_SEG(0x0001670000000398ull)) -#define CVMX_POW_ECC_ERR (CVMX_ADD_IO_SEG(0x0001670000000218ull)) -#define CVMX_POW_INT_CTL (CVMX_ADD_IO_SEG(0x0001670000000220ull)) -#define CVMX_POW_IQ_CNTX(offset) (CVMX_ADD_IO_SEG(0x0001670000000340ull) + ((offset) & 7) * 8) -#define CVMX_POW_IQ_COM_CNT (CVMX_ADD_IO_SEG(0x0001670000000388ull)) -#define CVMX_POW_IQ_INT (CVMX_ADD_IO_SEG(0x0001670000000238ull)) -#define CVMX_POW_IQ_INT_EN (CVMX_ADD_IO_SEG(0x0001670000000240ull)) -#define CVMX_POW_IQ_THRX(offset) (CVMX_ADD_IO_SEG(0x00016700000003A0ull) + ((offset) & 7) * 8) -#define CVMX_POW_NOS_CNT (CVMX_ADD_IO_SEG(0x0001670000000228ull)) -#define CVMX_POW_NW_TIM (CVMX_ADD_IO_SEG(0x0001670000000210ull)) -#define CVMX_POW_PF_RST_MSK (CVMX_ADD_IO_SEG(0x0001670000000230ull)) -#define CVMX_POW_PP_GRP_MSKX(offset) (CVMX_ADD_IO_SEG(0x0001670000000000ull) + ((offset) & 15) * 8) -#define CVMX_POW_QOS_RNDX(offset) (CVMX_ADD_IO_SEG(0x00016700000001C0ull) + ((offset) & 7) * 8) -#define CVMX_POW_QOS_THRX(offset) (CVMX_ADD_IO_SEG(0x0001670000000180ull) + ((offset) & 7) * 8) -#define CVMX_POW_TS_PC (CVMX_ADD_IO_SEG(0x0001670000000390ull)) -#define CVMX_POW_WA_COM_PC (CVMX_ADD_IO_SEG(0x0001670000000380ull)) -#define CVMX_POW_WA_PCX(offset) (CVMX_ADD_IO_SEG(0x0001670000000300ull) + ((offset) & 7) * 8) -#define CVMX_POW_WQ_INT (CVMX_ADD_IO_SEG(0x0001670000000200ull)) -#define CVMX_POW_WQ_INT_CNTX(offset) (CVMX_ADD_IO_SEG(0x0001670000000100ull) + ((offset) & 15) * 8) -#define CVMX_POW_WQ_INT_PC (CVMX_ADD_IO_SEG(0x0001670000000208ull)) -#define CVMX_POW_WQ_INT_THRX(offset) (CVMX_ADD_IO_SEG(0x0001670000000080ull) + ((offset) & 15) * 8) -#define CVMX_POW_WS_PCX(offset) (CVMX_ADD_IO_SEG(0x0001670000000280ull) + ((offset) & 15) * 8) +#define CVMX_POW_BIST_STAT \ + CVMX_ADD_IO_SEG(0x00016700000003F8ull) +#define CVMX_POW_DS_PC \ + CVMX_ADD_IO_SEG(0x0001670000000398ull) +#define CVMX_POW_ECC_ERR \ + CVMX_ADD_IO_SEG(0x0001670000000218ull) +#define CVMX_POW_INT_CTL \ + CVMX_ADD_IO_SEG(0x0001670000000220ull) +#define CVMX_POW_IQ_CNTX(offset) \ + CVMX_ADD_IO_SEG(0x0001670000000340ull + (((offset) & 7) * 8)) +#define CVMX_POW_IQ_COM_CNT \ + CVMX_ADD_IO_SEG(0x0001670000000388ull) +#define CVMX_POW_IQ_INT \ + CVMX_ADD_IO_SEG(0x0001670000000238ull) +#define CVMX_POW_IQ_INT_EN \ + CVMX_ADD_IO_SEG(0x0001670000000240ull) +#define CVMX_POW_IQ_THRX(offset) \ + CVMX_ADD_IO_SEG(0x00016700000003A0ull + (((offset) & 7) * 8)) +#define CVMX_POW_NOS_CNT \ + CVMX_ADD_IO_SEG(0x0001670000000228ull) +#define CVMX_POW_NW_TIM \ + CVMX_ADD_IO_SEG(0x0001670000000210ull) +#define CVMX_POW_PF_RST_MSK \ + CVMX_ADD_IO_SEG(0x0001670000000230ull) +#define CVMX_POW_PP_GRP_MSKX(offset) \ + CVMX_ADD_IO_SEG(0x0001670000000000ull + (((offset) & 15) * 8)) +#define CVMX_POW_QOS_RNDX(offset) \ + CVMX_ADD_IO_SEG(0x00016700000001C0ull + (((offset) & 7) * 8)) +#define CVMX_POW_QOS_THRX(offset) \ + CVMX_ADD_IO_SEG(0x0001670000000180ull + (((offset) & 7) * 8)) +#define CVMX_POW_TS_PC \ + CVMX_ADD_IO_SEG(0x0001670000000390ull) +#define CVMX_POW_WA_COM_PC \ + CVMX_ADD_IO_SEG(0x0001670000000380ull) +#define CVMX_POW_WA_PCX(offset) \ + CVMX_ADD_IO_SEG(0x0001670000000300ull + (((offset) & 7) * 8)) +#define CVMX_POW_WQ_INT \ + CVMX_ADD_IO_SEG(0x0001670000000200ull) +#define CVMX_POW_WQ_INT_CNTX(offset) \ + CVMX_ADD_IO_SEG(0x0001670000000100ull + (((offset) & 15) * 8)) +#define CVMX_POW_WQ_INT_PC \ + CVMX_ADD_IO_SEG(0x0001670000000208ull) +#define CVMX_POW_WQ_INT_THRX(offset) \ + CVMX_ADD_IO_SEG(0x0001670000000080ull + (((offset) & 15) * 8)) +#define CVMX_POW_WS_PCX(offset) \ + CVMX_ADD_IO_SEG(0x0001670000000280ull + (((offset) & 15) * 8)) union cvmx_pow_bist_stat { uint64_t u64; @@ -137,19 +160,6 @@ union cvmx_pow_bist_stat { struct cvmx_pow_bist_stat_cn56xx cn56xxp1; struct cvmx_pow_bist_stat_cn38xx cn58xx; struct cvmx_pow_bist_stat_cn38xx cn58xxp1; - struct cvmx_pow_bist_stat_cn63xx { - uint64_t reserved_22_63:42; - uint64_t pp:6; - uint64_t reserved_12_15:4; - uint64_t cam:1; - uint64_t nbr:3; - uint64_t nbt:4; - uint64_t index:1; - uint64_t fidx:1; - uint64_t pend:1; - uint64_t adr:1; - } cn63xx; - struct cvmx_pow_bist_stat_cn63xx cn63xxp1; }; union cvmx_pow_ds_pc { @@ -169,8 +179,6 @@ union cvmx_pow_ds_pc { struct cvmx_pow_ds_pc_s cn56xxp1; struct cvmx_pow_ds_pc_s cn58xx; struct cvmx_pow_ds_pc_s cn58xxp1; - struct cvmx_pow_ds_pc_s cn63xx; - struct cvmx_pow_ds_pc_s cn63xxp1; }; union cvmx_pow_ecc_err { @@ -211,8 +219,6 @@ union cvmx_pow_ecc_err { struct cvmx_pow_ecc_err_s cn56xxp1; struct cvmx_pow_ecc_err_s cn58xx; struct cvmx_pow_ecc_err_s cn58xxp1; - struct cvmx_pow_ecc_err_s cn63xx; - struct cvmx_pow_ecc_err_s cn63xxp1; }; union cvmx_pow_int_ctl { @@ -233,8 +239,6 @@ union cvmx_pow_int_ctl { struct cvmx_pow_int_ctl_s cn56xxp1; struct cvmx_pow_int_ctl_s cn58xx; struct cvmx_pow_int_ctl_s cn58xxp1; - struct cvmx_pow_int_ctl_s cn63xx; - struct cvmx_pow_int_ctl_s cn63xxp1; }; union cvmx_pow_iq_cntx { @@ -254,8 +258,6 @@ union cvmx_pow_iq_cntx { struct cvmx_pow_iq_cntx_s cn56xxp1; struct cvmx_pow_iq_cntx_s cn58xx; struct cvmx_pow_iq_cntx_s cn58xxp1; - struct cvmx_pow_iq_cntx_s cn63xx; - struct cvmx_pow_iq_cntx_s cn63xxp1; }; union cvmx_pow_iq_com_cnt { @@ -275,8 +277,6 @@ union cvmx_pow_iq_com_cnt { struct cvmx_pow_iq_com_cnt_s cn56xxp1; struct cvmx_pow_iq_com_cnt_s cn58xx; struct cvmx_pow_iq_com_cnt_s cn58xxp1; - struct cvmx_pow_iq_com_cnt_s cn63xx; - struct cvmx_pow_iq_com_cnt_s cn63xxp1; }; union cvmx_pow_iq_int { @@ -289,8 +289,6 @@ union cvmx_pow_iq_int { struct cvmx_pow_iq_int_s cn52xxp1; struct cvmx_pow_iq_int_s cn56xx; struct cvmx_pow_iq_int_s cn56xxp1; - struct cvmx_pow_iq_int_s cn63xx; - struct cvmx_pow_iq_int_s cn63xxp1; }; union cvmx_pow_iq_int_en { @@ -303,8 +301,6 @@ union cvmx_pow_iq_int_en { struct cvmx_pow_iq_int_en_s cn52xxp1; struct cvmx_pow_iq_int_en_s cn56xx; struct cvmx_pow_iq_int_en_s cn56xxp1; - struct cvmx_pow_iq_int_en_s cn63xx; - struct cvmx_pow_iq_int_en_s cn63xxp1; }; union cvmx_pow_iq_thrx { @@ -317,8 +313,6 @@ union cvmx_pow_iq_thrx { struct cvmx_pow_iq_thrx_s cn52xxp1; struct cvmx_pow_iq_thrx_s cn56xx; struct cvmx_pow_iq_thrx_s cn56xxp1; - struct cvmx_pow_iq_thrx_s cn63xx; - struct cvmx_pow_iq_thrx_s cn63xxp1; }; union cvmx_pow_nos_cnt { @@ -347,11 +341,6 @@ union cvmx_pow_nos_cnt { struct cvmx_pow_nos_cnt_s cn56xxp1; struct cvmx_pow_nos_cnt_s cn58xx; struct cvmx_pow_nos_cnt_s cn58xxp1; - struct cvmx_pow_nos_cnt_cn63xx { - uint64_t reserved_11_63:53; - uint64_t nos_cnt:11; - } cn63xx; - struct cvmx_pow_nos_cnt_cn63xx cn63xxp1; }; union cvmx_pow_nw_tim { @@ -371,8 +360,6 @@ union cvmx_pow_nw_tim { struct cvmx_pow_nw_tim_s cn56xxp1; struct cvmx_pow_nw_tim_s cn58xx; struct cvmx_pow_nw_tim_s cn58xxp1; - struct cvmx_pow_nw_tim_s cn63xx; - struct cvmx_pow_nw_tim_s cn63xxp1; }; union cvmx_pow_pf_rst_msk { @@ -388,8 +375,6 @@ union cvmx_pow_pf_rst_msk { struct cvmx_pow_pf_rst_msk_s cn56xxp1; struct cvmx_pow_pf_rst_msk_s cn58xx; struct cvmx_pow_pf_rst_msk_s cn58xxp1; - struct cvmx_pow_pf_rst_msk_s cn63xx; - struct cvmx_pow_pf_rst_msk_s cn63xxp1; }; union cvmx_pow_pp_grp_mskx { @@ -420,8 +405,6 @@ union cvmx_pow_pp_grp_mskx { struct cvmx_pow_pp_grp_mskx_s cn56xxp1; struct cvmx_pow_pp_grp_mskx_s cn58xx; struct cvmx_pow_pp_grp_mskx_s cn58xxp1; - struct cvmx_pow_pp_grp_mskx_s cn63xx; - struct cvmx_pow_pp_grp_mskx_s cn63xxp1; }; union cvmx_pow_qos_rndx { @@ -444,8 +427,6 @@ union cvmx_pow_qos_rndx { struct cvmx_pow_qos_rndx_s cn56xxp1; struct cvmx_pow_qos_rndx_s cn58xx; struct cvmx_pow_qos_rndx_s cn58xxp1; - struct cvmx_pow_qos_rndx_s cn63xx; - struct cvmx_pow_qos_rndx_s cn63xxp1; }; union cvmx_pow_qos_thrx { @@ -504,19 +485,6 @@ union cvmx_pow_qos_thrx { struct cvmx_pow_qos_thrx_s cn56xxp1; struct cvmx_pow_qos_thrx_s cn58xx; struct cvmx_pow_qos_thrx_s cn58xxp1; - struct cvmx_pow_qos_thrx_cn63xx { - uint64_t reserved_59_63:5; - uint64_t des_cnt:11; - uint64_t reserved_47_47:1; - uint64_t buf_cnt:11; - uint64_t reserved_35_35:1; - uint64_t free_cnt:11; - uint64_t reserved_22_23:2; - uint64_t max_thr:10; - uint64_t reserved_10_11:2; - uint64_t min_thr:10; - } cn63xx; - struct cvmx_pow_qos_thrx_cn63xx cn63xxp1; }; union cvmx_pow_ts_pc { @@ -536,8 +504,6 @@ union cvmx_pow_ts_pc { struct cvmx_pow_ts_pc_s cn56xxp1; struct cvmx_pow_ts_pc_s cn58xx; struct cvmx_pow_ts_pc_s cn58xxp1; - struct cvmx_pow_ts_pc_s cn63xx; - struct cvmx_pow_ts_pc_s cn63xxp1; }; union cvmx_pow_wa_com_pc { @@ -557,8 +523,6 @@ union cvmx_pow_wa_com_pc { struct cvmx_pow_wa_com_pc_s cn56xxp1; struct cvmx_pow_wa_com_pc_s cn58xx; struct cvmx_pow_wa_com_pc_s cn58xxp1; - struct cvmx_pow_wa_com_pc_s cn63xx; - struct cvmx_pow_wa_com_pc_s cn63xxp1; }; union cvmx_pow_wa_pcx { @@ -578,8 +542,6 @@ union cvmx_pow_wa_pcx { struct cvmx_pow_wa_pcx_s cn56xxp1; struct cvmx_pow_wa_pcx_s cn58xx; struct cvmx_pow_wa_pcx_s cn58xxp1; - struct cvmx_pow_wa_pcx_s cn63xx; - struct cvmx_pow_wa_pcx_s cn63xxp1; }; union cvmx_pow_wq_int { @@ -600,8 +562,6 @@ union cvmx_pow_wq_int { struct cvmx_pow_wq_int_s cn56xxp1; struct cvmx_pow_wq_int_s cn58xx; struct cvmx_pow_wq_int_s cn58xxp1; - struct cvmx_pow_wq_int_s cn63xx; - struct cvmx_pow_wq_int_s cn63xxp1; }; union cvmx_pow_wq_int_cntx { @@ -644,15 +604,6 @@ union cvmx_pow_wq_int_cntx { struct cvmx_pow_wq_int_cntx_s cn56xxp1; struct cvmx_pow_wq_int_cntx_s cn58xx; struct cvmx_pow_wq_int_cntx_s cn58xxp1; - struct cvmx_pow_wq_int_cntx_cn63xx { - uint64_t reserved_28_63:36; - uint64_t tc_cnt:4; - uint64_t reserved_23_23:1; - uint64_t ds_cnt:11; - uint64_t reserved_11_11:1; - uint64_t iq_cnt:11; - } cn63xx; - struct cvmx_pow_wq_int_cntx_cn63xx cn63xxp1; }; union cvmx_pow_wq_int_pc { @@ -675,8 +626,6 @@ union cvmx_pow_wq_int_pc { struct cvmx_pow_wq_int_pc_s cn56xxp1; struct cvmx_pow_wq_int_pc_s cn58xx; struct cvmx_pow_wq_int_pc_s cn58xxp1; - struct cvmx_pow_wq_int_pc_s cn63xx; - struct cvmx_pow_wq_int_pc_s cn63xxp1; }; union cvmx_pow_wq_int_thrx { @@ -725,16 +674,6 @@ union cvmx_pow_wq_int_thrx { struct cvmx_pow_wq_int_thrx_s cn56xxp1; struct cvmx_pow_wq_int_thrx_s cn58xx; struct cvmx_pow_wq_int_thrx_s cn58xxp1; - struct cvmx_pow_wq_int_thrx_cn63xx { - uint64_t reserved_29_63:35; - uint64_t tc_en:1; - uint64_t tc_thr:4; - uint64_t reserved_22_23:2; - uint64_t ds_thr:10; - uint64_t reserved_10_11:2; - uint64_t iq_thr:10; - } cn63xx; - struct cvmx_pow_wq_int_thrx_cn63xx cn63xxp1; }; union cvmx_pow_ws_pcx { @@ -754,8 +693,6 @@ union cvmx_pow_ws_pcx { struct cvmx_pow_ws_pcx_s cn56xxp1; struct cvmx_pow_ws_pcx_s cn58xx; struct cvmx_pow_ws_pcx_s cn58xxp1; - struct cvmx_pow_ws_pcx_s cn63xx; - struct cvmx_pow_ws_pcx_s cn63xxp1; }; #endif diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-rnm-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-rnm-defs.h index c45da1f35ea7..4586958c97be 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-rnm-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-rnm-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -30,11 +30,10 @@ #include -#define CVMX_RNM_BIST_STATUS (CVMX_ADD_IO_SEG(0x0001180040000008ull)) -#define CVMX_RNM_CTL_STATUS (CVMX_ADD_IO_SEG(0x0001180040000000ull)) -#define CVMX_RNM_EER_DBG (CVMX_ADD_IO_SEG(0x0001180040000018ull)) -#define CVMX_RNM_EER_KEY (CVMX_ADD_IO_SEG(0x0001180040000010ull)) -#define CVMX_RNM_SERIAL_NUM (CVMX_ADD_IO_SEG(0x0001180040000020ull)) +#define CVMX_RNM_BIST_STATUS \ + CVMX_ADD_IO_SEG(0x0001180040000008ull) +#define CVMX_RNM_CTL_STATUS \ + CVMX_ADD_IO_SEG(0x0001180040000000ull) union cvmx_rnm_bist_status { uint64_t u64; @@ -54,16 +53,12 @@ union cvmx_rnm_bist_status { struct cvmx_rnm_bist_status_s cn56xxp1; struct cvmx_rnm_bist_status_s cn58xx; struct cvmx_rnm_bist_status_s cn58xxp1; - struct cvmx_rnm_bist_status_s cn63xx; - struct cvmx_rnm_bist_status_s cn63xxp1; }; union cvmx_rnm_ctl_status { uint64_t u64; struct cvmx_rnm_ctl_status_s { - uint64_t reserved_11_63:53; - uint64_t eer_lck:1; - uint64_t eer_val:1; + uint64_t reserved_9_63:55; uint64_t ent_sel:4; uint64_t exp_ent:1; uint64_t rng_rst:1; @@ -81,49 +76,13 @@ union cvmx_rnm_ctl_status { struct cvmx_rnm_ctl_status_cn30xx cn31xx; struct cvmx_rnm_ctl_status_cn30xx cn38xx; struct cvmx_rnm_ctl_status_cn30xx cn38xxp2; - struct cvmx_rnm_ctl_status_cn50xx { - uint64_t reserved_9_63:55; - uint64_t ent_sel:4; - uint64_t exp_ent:1; - uint64_t rng_rst:1; - uint64_t rnm_rst:1; - uint64_t rng_en:1; - uint64_t ent_en:1; - } cn50xx; - struct cvmx_rnm_ctl_status_cn50xx cn52xx; - struct cvmx_rnm_ctl_status_cn50xx cn52xxp1; - struct cvmx_rnm_ctl_status_cn50xx cn56xx; - struct cvmx_rnm_ctl_status_cn50xx cn56xxp1; - struct cvmx_rnm_ctl_status_cn50xx cn58xx; - struct cvmx_rnm_ctl_status_cn50xx cn58xxp1; - struct cvmx_rnm_ctl_status_s cn63xx; - struct cvmx_rnm_ctl_status_s cn63xxp1; -}; - -union cvmx_rnm_eer_dbg { - uint64_t u64; - struct cvmx_rnm_eer_dbg_s { - uint64_t dat:64; - } s; - struct cvmx_rnm_eer_dbg_s cn63xx; - struct cvmx_rnm_eer_dbg_s cn63xxp1; -}; - -union cvmx_rnm_eer_key { - uint64_t u64; - struct cvmx_rnm_eer_key_s { - uint64_t key:64; - } s; - struct cvmx_rnm_eer_key_s cn63xx; - struct cvmx_rnm_eer_key_s cn63xxp1; -}; - -union cvmx_rnm_serial_num { - uint64_t u64; - struct cvmx_rnm_serial_num_s { - uint64_t dat:64; - } s; - struct cvmx_rnm_serial_num_s cn63xx; + struct cvmx_rnm_ctl_status_s cn50xx; + struct cvmx_rnm_ctl_status_s cn52xx; + struct cvmx_rnm_ctl_status_s cn52xxp1; + struct cvmx_rnm_ctl_status_s cn56xx; + struct cvmx_rnm_ctl_status_s cn56xxp1; + struct cvmx_rnm_ctl_status_s cn58xx; + struct cvmx_rnm_ctl_status_s cn58xxp1; }; #endif diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-smix-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-smix-defs.h index 4f3c0666e94a..9ae45fcbe3e3 100644 --- a/trunk/arch/mips/include/asm/octeon/cvmx-smix-defs.h +++ b/trunk/arch/mips/include/asm/octeon/cvmx-smix-defs.h @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2008 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 @@ -28,11 +28,16 @@ #ifndef __CVMX_SMIX_DEFS_H__ #define __CVMX_SMIX_DEFS_H__ -#define CVMX_SMIX_CLK(offset) (CVMX_ADD_IO_SEG(0x0001180000001818ull) + ((offset) & 1) * 256) -#define CVMX_SMIX_CMD(offset) (CVMX_ADD_IO_SEG(0x0001180000001800ull) + ((offset) & 1) * 256) -#define CVMX_SMIX_EN(offset) (CVMX_ADD_IO_SEG(0x0001180000001820ull) + ((offset) & 1) * 256) -#define CVMX_SMIX_RD_DAT(offset) (CVMX_ADD_IO_SEG(0x0001180000001810ull) + ((offset) & 1) * 256) -#define CVMX_SMIX_WR_DAT(offset) (CVMX_ADD_IO_SEG(0x0001180000001808ull) + ((offset) & 1) * 256) +#define CVMX_SMIX_CLK(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001818ull + (((offset) & 1) * 256)) +#define CVMX_SMIX_CMD(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001800ull + (((offset) & 1) * 256)) +#define CVMX_SMIX_EN(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001820ull + (((offset) & 1) * 256)) +#define CVMX_SMIX_RD_DAT(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001810ull + (((offset) & 1) * 256)) +#define CVMX_SMIX_WR_DAT(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001808ull + (((offset) & 1) * 256)) union cvmx_smix_clk { uint64_t u64; @@ -51,8 +56,7 @@ union cvmx_smix_clk { struct cvmx_smix_clk_cn30xx { uint64_t reserved_21_63:43; uint64_t sample_hi:5; - uint64_t sample_mode:1; - uint64_t reserved_14_14:1; + uint64_t reserved_14_15:2; uint64_t clk_idle:1; uint64_t preamble:1; uint64_t sample:4; @@ -61,15 +65,23 @@ union cvmx_smix_clk { struct cvmx_smix_clk_cn30xx cn31xx; struct cvmx_smix_clk_cn30xx cn38xx; struct cvmx_smix_clk_cn30xx cn38xxp2; - struct cvmx_smix_clk_s cn50xx; + struct cvmx_smix_clk_cn50xx { + uint64_t reserved_25_63:39; + uint64_t mode:1; + uint64_t reserved_21_23:3; + uint64_t sample_hi:5; + uint64_t reserved_14_15:2; + uint64_t clk_idle:1; + uint64_t preamble:1; + uint64_t sample:4; + uint64_t phase:8; + } cn50xx; struct cvmx_smix_clk_s cn52xx; - struct cvmx_smix_clk_s cn52xxp1; + struct cvmx_smix_clk_cn50xx cn52xxp1; struct cvmx_smix_clk_s cn56xx; - struct cvmx_smix_clk_s cn56xxp1; + struct cvmx_smix_clk_cn50xx cn56xxp1; struct cvmx_smix_clk_cn30xx cn58xx; struct cvmx_smix_clk_cn30xx cn58xxp1; - struct cvmx_smix_clk_s cn63xx; - struct cvmx_smix_clk_s cn63xxp1; }; union cvmx_smix_cmd { @@ -100,8 +112,6 @@ union cvmx_smix_cmd { struct cvmx_smix_cmd_s cn56xxp1; struct cvmx_smix_cmd_cn30xx cn58xx; struct cvmx_smix_cmd_cn30xx cn58xxp1; - struct cvmx_smix_cmd_s cn63xx; - struct cvmx_smix_cmd_s cn63xxp1; }; union cvmx_smix_en { @@ -121,8 +131,6 @@ union cvmx_smix_en { struct cvmx_smix_en_s cn56xxp1; struct cvmx_smix_en_s cn58xx; struct cvmx_smix_en_s cn58xxp1; - struct cvmx_smix_en_s cn63xx; - struct cvmx_smix_en_s cn63xxp1; }; union cvmx_smix_rd_dat { @@ -144,8 +152,6 @@ union cvmx_smix_rd_dat { struct cvmx_smix_rd_dat_s cn56xxp1; struct cvmx_smix_rd_dat_s cn58xx; struct cvmx_smix_rd_dat_s cn58xxp1; - struct cvmx_smix_rd_dat_s cn63xx; - struct cvmx_smix_rd_dat_s cn63xxp1; }; union cvmx_smix_wr_dat { @@ -167,8 +173,6 @@ union cvmx_smix_wr_dat { struct cvmx_smix_wr_dat_s cn56xxp1; struct cvmx_smix_wr_dat_s cn58xx; struct cvmx_smix_wr_dat_s cn58xxp1; - struct cvmx_smix_wr_dat_s cn63xx; - struct cvmx_smix_wr_dat_s cn63xxp1; }; #endif diff --git a/trunk/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h b/trunk/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h deleted file mode 100644 index 594f1b68cd62..000000000000 --- a/trunk/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h +++ /dev/null @@ -1,261 +0,0 @@ -/***********************license start*************** - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK - * - * 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 - * published by the Free Software Foundation. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information - ***********************license end**************************************/ - -#ifndef __CVMX_UCTLX_TYPEDEFS_H__ -#define __CVMX_UCTLX_TYPEDEFS_H__ - -#define CVMX_UCTLX_BIST_STATUS(block_id) (CVMX_ADD_IO_SEG(0x000118006F0000A0ull)) -#define CVMX_UCTLX_CLK_RST_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000000ull)) -#define CVMX_UCTLX_EHCI_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000080ull)) -#define CVMX_UCTLX_EHCI_FLA(block_id) (CVMX_ADD_IO_SEG(0x000118006F0000A8ull)) -#define CVMX_UCTLX_ERTO_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000090ull)) -#define CVMX_UCTLX_IF_ENA(block_id) (CVMX_ADD_IO_SEG(0x000118006F000030ull)) -#define CVMX_UCTLX_INT_ENA(block_id) (CVMX_ADD_IO_SEG(0x000118006F000028ull)) -#define CVMX_UCTLX_INT_REG(block_id) (CVMX_ADD_IO_SEG(0x000118006F000020ull)) -#define CVMX_UCTLX_OHCI_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000088ull)) -#define CVMX_UCTLX_ORTO_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000098ull)) -#define CVMX_UCTLX_PPAF_WM(block_id) (CVMX_ADD_IO_SEG(0x000118006F000038ull)) -#define CVMX_UCTLX_UPHY_CTL_STATUS(block_id) (CVMX_ADD_IO_SEG(0x000118006F000008ull)) -#define CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(offset, block_id) (CVMX_ADD_IO_SEG(0x000118006F000010ull) + (((offset) & 1) + ((block_id) & 0) * 0x0ull) * 8) - -union cvmx_uctlx_bist_status { - uint64_t u64; - struct cvmx_uctlx_bist_status_s { - uint64_t reserved_6_63:58; - uint64_t data_bis:1; - uint64_t desc_bis:1; - uint64_t erbm_bis:1; - uint64_t orbm_bis:1; - uint64_t wrbm_bis:1; - uint64_t ppaf_bis:1; - } s; - struct cvmx_uctlx_bist_status_s cn63xx; - struct cvmx_uctlx_bist_status_s cn63xxp1; -}; - -union cvmx_uctlx_clk_rst_ctl { - uint64_t u64; - struct cvmx_uctlx_clk_rst_ctl_s { - uint64_t reserved_25_63:39; - uint64_t clear_bist:1; - uint64_t start_bist:1; - uint64_t ehci_sm:1; - uint64_t ohci_clkcktrst:1; - uint64_t ohci_sm:1; - uint64_t ohci_susp_lgcy:1; - uint64_t app_start_clk:1; - uint64_t o_clkdiv_rst:1; - uint64_t h_clkdiv_byp:1; - uint64_t h_clkdiv_rst:1; - uint64_t h_clkdiv_en:1; - uint64_t o_clkdiv_en:1; - uint64_t h_div:4; - uint64_t p_refclk_sel:2; - uint64_t p_refclk_div:2; - uint64_t reserved_4_4:1; - uint64_t p_com_on:1; - uint64_t p_por:1; - uint64_t p_prst:1; - uint64_t hrst:1; - } s; - struct cvmx_uctlx_clk_rst_ctl_s cn63xx; - struct cvmx_uctlx_clk_rst_ctl_s cn63xxp1; -}; - -union cvmx_uctlx_ehci_ctl { - uint64_t u64; - struct cvmx_uctlx_ehci_ctl_s { - uint64_t reserved_20_63:44; - uint64_t desc_rbm:1; - uint64_t reg_nb:1; - uint64_t l2c_dc:1; - uint64_t l2c_bc:1; - uint64_t l2c_0pag:1; - uint64_t l2c_stt:1; - uint64_t l2c_buff_emod:2; - uint64_t l2c_desc_emod:2; - uint64_t inv_reg_a2:1; - uint64_t ehci_64b_addr_en:1; - uint64_t l2c_addr_msb:8; - } s; - struct cvmx_uctlx_ehci_ctl_s cn63xx; - struct cvmx_uctlx_ehci_ctl_s cn63xxp1; -}; - -union cvmx_uctlx_ehci_fla { - uint64_t u64; - struct cvmx_uctlx_ehci_fla_s { - uint64_t reserved_6_63:58; - uint64_t fla:6; - } s; - struct cvmx_uctlx_ehci_fla_s cn63xx; - struct cvmx_uctlx_ehci_fla_s cn63xxp1; -}; - -union cvmx_uctlx_erto_ctl { - uint64_t u64; - struct cvmx_uctlx_erto_ctl_s { - uint64_t reserved_32_63:32; - uint64_t to_val:27; - uint64_t reserved_0_4:5; - } s; - struct cvmx_uctlx_erto_ctl_s cn63xx; - struct cvmx_uctlx_erto_ctl_s cn63xxp1; -}; - -union cvmx_uctlx_if_ena { - uint64_t u64; - struct cvmx_uctlx_if_ena_s { - uint64_t reserved_1_63:63; - uint64_t en:1; - } s; - struct cvmx_uctlx_if_ena_s cn63xx; - struct cvmx_uctlx_if_ena_s cn63xxp1; -}; - -union cvmx_uctlx_int_ena { - uint64_t u64; - struct cvmx_uctlx_int_ena_s { - uint64_t reserved_8_63:56; - uint64_t ec_ovf_e:1; - uint64_t oc_ovf_e:1; - uint64_t wb_pop_e:1; - uint64_t wb_psh_f:1; - uint64_t cf_psh_f:1; - uint64_t or_psh_f:1; - uint64_t er_psh_f:1; - uint64_t pp_psh_f:1; - } s; - struct cvmx_uctlx_int_ena_s cn63xx; - struct cvmx_uctlx_int_ena_s cn63xxp1; -}; - -union cvmx_uctlx_int_reg { - uint64_t u64; - struct cvmx_uctlx_int_reg_s { - uint64_t reserved_8_63:56; - uint64_t ec_ovf_e:1; - uint64_t oc_ovf_e:1; - uint64_t wb_pop_e:1; - uint64_t wb_psh_f:1; - uint64_t cf_psh_f:1; - uint64_t or_psh_f:1; - uint64_t er_psh_f:1; - uint64_t pp_psh_f:1; - } s; - struct cvmx_uctlx_int_reg_s cn63xx; - struct cvmx_uctlx_int_reg_s cn63xxp1; -}; - -union cvmx_uctlx_ohci_ctl { - uint64_t u64; - struct cvmx_uctlx_ohci_ctl_s { - uint64_t reserved_19_63:45; - uint64_t reg_nb:1; - uint64_t l2c_dc:1; - uint64_t l2c_bc:1; - uint64_t l2c_0pag:1; - uint64_t l2c_stt:1; - uint64_t l2c_buff_emod:2; - uint64_t l2c_desc_emod:2; - uint64_t inv_reg_a2:1; - uint64_t reserved_8_8:1; - uint64_t l2c_addr_msb:8; - } s; - struct cvmx_uctlx_ohci_ctl_s cn63xx; - struct cvmx_uctlx_ohci_ctl_s cn63xxp1; -}; - -union cvmx_uctlx_orto_ctl { - uint64_t u64; - struct cvmx_uctlx_orto_ctl_s { - uint64_t reserved_32_63:32; - uint64_t to_val:24; - uint64_t reserved_0_7:8; - } s; - struct cvmx_uctlx_orto_ctl_s cn63xx; - struct cvmx_uctlx_orto_ctl_s cn63xxp1; -}; - -union cvmx_uctlx_ppaf_wm { - uint64_t u64; - struct cvmx_uctlx_ppaf_wm_s { - uint64_t reserved_5_63:59; - uint64_t wm:5; - } s; - struct cvmx_uctlx_ppaf_wm_s cn63xx; - struct cvmx_uctlx_ppaf_wm_s cn63xxp1; -}; - -union cvmx_uctlx_uphy_ctl_status { - uint64_t u64; - struct cvmx_uctlx_uphy_ctl_status_s { - uint64_t reserved_10_63:54; - uint64_t bist_done:1; - uint64_t bist_err:1; - uint64_t hsbist:1; - uint64_t fsbist:1; - uint64_t lsbist:1; - uint64_t siddq:1; - uint64_t vtest_en:1; - uint64_t uphy_bist:1; - uint64_t bist_en:1; - uint64_t ate_reset:1; - } s; - struct cvmx_uctlx_uphy_ctl_status_s cn63xx; - struct cvmx_uctlx_uphy_ctl_status_s cn63xxp1; -}; - -union cvmx_uctlx_uphy_portx_ctl_status { - uint64_t u64; - struct cvmx_uctlx_uphy_portx_ctl_status_s { - uint64_t reserved_43_63:21; - uint64_t tdata_out:4; - uint64_t txbiststuffenh:1; - uint64_t txbiststuffen:1; - uint64_t dmpulldown:1; - uint64_t dppulldown:1; - uint64_t vbusvldext:1; - uint64_t portreset:1; - uint64_t txhsvxtune:2; - uint64_t txvreftune:4; - uint64_t txrisetune:1; - uint64_t txpreemphasistune:1; - uint64_t txfslstune:4; - uint64_t sqrxtune:3; - uint64_t compdistune:3; - uint64_t loop_en:1; - uint64_t tclk:1; - uint64_t tdata_sel:1; - uint64_t taddr_in:4; - uint64_t tdata_in:8; - } s; - struct cvmx_uctlx_uphy_portx_ctl_status_s cn63xx; - struct cvmx_uctlx_uphy_portx_ctl_status_s cn63xxp1; -}; - -#endif diff --git a/trunk/arch/mips/include/asm/octeon/octeon-model.h b/trunk/arch/mips/include/asm/octeon/octeon-model.h index 700f88e31cad..cf50336eca2e 100644 --- a/trunk/arch/mips/include/asm/octeon/octeon-model.h +++ b/trunk/arch/mips/include/asm/octeon/octeon-model.h @@ -35,6 +35,14 @@ #ifndef __OCTEON_MODEL_H__ #define __OCTEON_MODEL_H__ +/* NOTE: These must match what is checked in common-config.mk */ +/* Defines to represent the different versions of Octeon. */ + +/* + * IMPORTANT: When the default pass is updated for an Octeon Model, + * the corresponding change must also be made in the oct-sim script. + */ + /* * The defines below should be used with the OCTEON_IS_MODEL() macro * to determine what model of chip the software is running on. Models @@ -63,21 +71,6 @@ #define OM_IGNORE_MINOR_REVISION 0x08000000 #define OM_FLAG_MASK 0xff000000 -#define OM_MATCH_5XXX_FAMILY_MODELS 0x20000000 /* Match all cn5XXX Octeon models. */ -#define OM_MATCH_6XXX_FAMILY_MODELS 0x40000000 /* Match all cn6XXX Octeon models. */ - -/* - * CN6XXX models with new revision encoding - */ -#define OCTEON_CN63XX_PASS1_0 0x000d9000 -#define OCTEON_CN63XX_PASS1_1 0x000d9001 -#define OCTEON_CN63XX_PASS1_2 0x000d9002 -#define OCTEON_CN63XX_PASS2_0 0x000d9008 - -#define OCTEON_CN63XX (OCTEON_CN63XX_PASS2_0 | OM_IGNORE_REVISION) -#define OCTEON_CN63XX_PASS1_X (OCTEON_CN63XX_PASS1_0 | OM_IGNORE_MINOR_REVISION) -#define OCTEON_CN63XX_PASS2_X (OCTEON_CN63XX_PASS2_0 | OM_IGNORE_MINOR_REVISION) - /* * CN5XXX models with new revision encoding */ @@ -196,9 +189,6 @@ | OM_MATCH_PREVIOUS_MODELS \ | OM_IGNORE_REVISION) -#define OCTEON_CN5XXX (OCTEON_CN58XX_PASS1_0 | OM_MATCH_5XXX_FAMILY_MODELS) -#define OCTEON_CN6XXX (OCTEON_CN63XX_PASS1_0 | OM_MATCH_6XXX_FAMILY_MODELS) - /* The revision byte (low byte) has two different encodings. * CN3XXX: * @@ -232,7 +222,6 @@ | OCTEON_58XX_MODEL_MASK) #define OCTEON_58XX_MODEL_MINOR_REV_MASK (OCTEON_58XX_MODEL_REV_MASK \ & 0x00fffff8) -#define OCTEON_5XXX_MODEL_MASK 0x00ff0fc0 #define __OCTEON_MATCH_MASK__(x, y, z) (((x) & (z)) == ((y) & (z))) @@ -284,15 +273,6 @@ static inline int __OCTEON_IS_MODEL_COMPILE__(uint32_t arg_model, __OCTEON_MATCH_MASK__((chip_model), (arg_model), OCTEON_58XX_MODEL_REV_MASK)) return 1; - - if (((arg_model & OM_MATCH_5XXX_FAMILY_MODELS) == OM_MATCH_5XXX_FAMILY_MODELS) && - ((chip_model) >= OCTEON_CN58XX_PASS1_0) && ((chip_model) < OCTEON_CN63XX_PASS1_0)) - return 1; - - if (((arg_model & OM_MATCH_6XXX_FAMILY_MODELS) == OM_MATCH_6XXX_FAMILY_MODELS) && - ((chip_model) >= OCTEON_CN63XX_PASS1_0)) - return 1; - if ((arg_model & OM_MATCH_PREVIOUS_MODELS) && ((chip_model & OCTEON_58XX_MODEL_MASK) < (arg_model & OCTEON_58XX_MODEL_MASK))) diff --git a/trunk/arch/mips/include/asm/octeon/octeon.h b/trunk/arch/mips/include/asm/octeon/octeon.h index 6b34afd0d4e7..917a6c413b1a 100644 --- a/trunk/arch/mips/include/asm/octeon/octeon.h +++ b/trunk/arch/mips/include/asm/octeon/octeon.h @@ -35,7 +35,6 @@ extern int octeon_is_simulation(void); extern int octeon_is_pci_host(void); extern int octeon_usb_is_ref_clk(void); extern uint64_t octeon_get_clock_rate(void); -extern u64 octeon_get_io_clock_rate(void); extern const char *octeon_board_type_string(void); extern const char *octeon_get_pci_interrupts(void); extern int octeon_get_southbridge_interrupt(void); diff --git a/trunk/arch/mips/include/asm/octeon/pci-octeon.h b/trunk/arch/mips/include/asm/octeon/pci-octeon.h index fba2ba200f58..ece78043acf6 100644 --- a/trunk/arch/mips/include/asm/octeon/pci-octeon.h +++ b/trunk/arch/mips/include/asm/octeon/pci-octeon.h @@ -35,16 +35,6 @@ extern int (*octeon_pcibios_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); -/* - * For PCI (not PCIe) the BAR2 base address. - */ -#define OCTEON_BAR2_PCI_ADDRESS 0x8000000000ull - -/* - * For PCI (not PCIe) the base of the memory mapped by BAR1 - */ -extern u64 octeon_bar1_pci_phys; - /* * The following defines are used when octeon_dma_bar_type = * OCTEON_DMA_BAR_TYPE_BIG diff --git a/trunk/arch/mips/include/asm/perf_event.h b/trunk/arch/mips/include/asm/perf_event.h deleted file mode 100644 index e00007cf8162..000000000000 --- a/trunk/arch/mips/include/asm/perf_event.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * linux/arch/mips/include/asm/perf_event.h - * - * Copyright (C) 2010 MIPS Technologies, Inc. - * Author: Deng-Cheng Zhu - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __MIPS_PERF_EVENT_H__ -#define __MIPS_PERF_EVENT_H__ - -/* - * MIPS performance counters do not raise NMI upon overflow, a regular - * interrupt will be signaled. Hence we can do the pending perf event - * work at the tail of the irq handler. - */ -static inline void -set_perf_event_pending(void) -{ -} - -#endif /* __MIPS_PERF_EVENT_H__ */ diff --git a/trunk/arch/mips/include/asm/pgtable-64.h b/trunk/arch/mips/include/asm/pgtable-64.h index 55908fd56b1f..f00896087dda 100644 --- a/trunk/arch/mips/include/asm/pgtable-64.h +++ b/trunk/arch/mips/include/asm/pgtable-64.h @@ -113,10 +113,10 @@ #endif #define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t)) -#if PGDIR_SIZE >= TASK_SIZE64 +#if PGDIR_SIZE >= TASK_SIZE #define USER_PTRS_PER_PGD (1) #else -#define USER_PTRS_PER_PGD (TASK_SIZE64 / PGDIR_SIZE) +#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) #endif #define FIRST_USER_ADDRESS 0UL diff --git a/trunk/arch/mips/include/asm/processor.h b/trunk/arch/mips/include/asm/processor.h index ead6928fa6b8..0d629bb93cbe 100644 --- a/trunk/arch/mips/include/asm/processor.h +++ b/trunk/arch/mips/include/asm/processor.h @@ -50,10 +50,13 @@ extern unsigned int vced_count, vcei_count; * so don't change it unless you know what you are doing. */ #define TASK_SIZE 0x7fff8000UL +#define STACK_TOP ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE) -#ifdef __KERNEL__ -#define STACK_TOP_MAX TASK_SIZE -#endif +/* + * This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define TASK_UNMAPPED_BASE ((TASK_SIZE / 3) & ~(PAGE_SIZE)) #define TASK_IS_32BIT_ADDR 1 @@ -68,29 +71,28 @@ extern unsigned int vced_count, vcei_count; * 8192EB ... */ #define TASK_SIZE32 0x7fff8000UL -#define TASK_SIZE64 0x10000000000UL -#define TASK_SIZE (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64) - -#ifdef __KERNEL__ -#define STACK_TOP_MAX TASK_SIZE64 -#endif - +#define TASK_SIZE 0x10000000000UL +#define STACK_TOP \ + (((test_thread_flag(TIF_32BIT_ADDR) ? \ + TASK_SIZE32 : TASK_SIZE) & PAGE_MASK) - SPECIAL_PAGES_SIZE) +/* + * This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define TASK_UNMAPPED_BASE \ + (test_thread_flag(TIF_32BIT_ADDR) ? \ + PAGE_ALIGN(TASK_SIZE32 / 3) : PAGE_ALIGN(TASK_SIZE / 3)) #define TASK_SIZE_OF(tsk) \ - (test_tsk_thread_flag(tsk, TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64) + (test_tsk_thread_flag(tsk, TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE) #define TASK_IS_32BIT_ADDR test_thread_flag(TIF_32BIT_ADDR) #endif -#define STACK_TOP ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE) - -/* - * This decides where the kernel will search for a free chunk of vm - * space during mmap's. - */ -#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3) - +#ifdef __KERNEL__ +#define STACK_TOP_MAX TASK_SIZE +#endif #define NUM_FPU_REGS 32 diff --git a/trunk/arch/mips/include/asm/system.h b/trunk/arch/mips/include/asm/system.h index 6018c80ce37a..bb937ccfba1e 100644 --- a/trunk/arch/mips/include/asm/system.h +++ b/trunk/arch/mips/include/asm/system.h @@ -115,19 +115,21 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) } else if (kernel_uses_llsc) { unsigned long dummy; - do { - __asm__ __volatile__( - " .set mips3 \n" - " ll %0, %3 # xchg_u32 \n" - " .set mips0 \n" - " move %2, %z4 \n" - " .set mips3 \n" - " sc %2, %1 \n" - " .set mips0 \n" - : "=&r" (retval), "=m" (*m), "=&r" (dummy) - : "R" (*m), "Jr" (val) - : "memory"); - } while (unlikely(!dummy)); + __asm__ __volatile__( + " .set mips3 \n" + "1: ll %0, %3 # xchg_u32 \n" + " .set mips0 \n" + " move %2, %z4 \n" + " .set mips3 \n" + " sc %2, %1 \n" + " beqz %2, 2f \n" + " .subsection 2 \n" + "2: b 1b \n" + " .previous \n" + " .set mips0 \n" + : "=&r" (retval), "=m" (*m), "=&r" (dummy) + : "R" (*m), "Jr" (val) + : "memory"); } else { unsigned long flags; @@ -165,17 +167,19 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val) } else if (kernel_uses_llsc) { unsigned long dummy; - do { - __asm__ __volatile__( - " .set mips3 \n" - " lld %0, %3 # xchg_u64 \n" - " move %2, %z4 \n" - " scd %2, %1 \n" - " .set mips0 \n" - : "=&r" (retval), "=m" (*m), "=&r" (dummy) - : "R" (*m), "Jr" (val) - : "memory"); - } while (unlikely(!dummy)); + __asm__ __volatile__( + " .set mips3 \n" + "1: lld %0, %3 # xchg_u64 \n" + " move %2, %z4 \n" + " scd %2, %1 \n" + " beqz %2, 2f \n" + " .subsection 2 \n" + "2: b 1b \n" + " .previous \n" + " .set mips0 \n" + : "=&r" (retval), "=m" (*m), "=&r" (dummy) + : "R" (*m), "Jr" (val) + : "memory"); } else { unsigned long flags; diff --git a/trunk/arch/mips/include/asm/thread_info.h b/trunk/arch/mips/include/asm/thread_info.h index d309556cacf8..70df9c0d3c5b 100644 --- a/trunk/arch/mips/include/asm/thread_info.h +++ b/trunk/arch/mips/include/asm/thread_info.h @@ -83,8 +83,6 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) #define THREAD_MASK (THREAD_SIZE - 1UL) -#define STACK_WARN (THREAD_SIZE / 8) - #define __HAVE_ARCH_THREAD_INFO_ALLOCATOR #ifdef CONFIG_DEBUG_STACK_USAGE diff --git a/trunk/arch/mips/include/asm/uaccess.h b/trunk/arch/mips/include/asm/uaccess.h index 653a412c036c..c2d53c18fd36 100644 --- a/trunk/arch/mips/include/asm/uaccess.h +++ b/trunk/arch/mips/include/asm/uaccess.h @@ -35,9 +35,7 @@ #ifdef CONFIG_64BIT -extern u64 __ua_limit; - -#define __UA_LIMIT __ua_limit +#define __UA_LIMIT (- TASK_SIZE) #define __UA_ADDR ".dword" #define __UA_LA "dla" diff --git a/trunk/arch/mips/kernel/Makefile b/trunk/arch/mips/kernel/Makefile index 22b2e0e38617..80884983270d 100644 --- a/trunk/arch/mips/kernel/Makefile +++ b/trunk/arch/mips/kernel/Makefile @@ -104,6 +104,4 @@ obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/ -obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o - CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS) diff --git a/trunk/arch/mips/kernel/cpu-probe.c b/trunk/arch/mips/kernel/cpu-probe.c index 71620e19827a..b1b304ea2128 100644 --- a/trunk/arch/mips/kernel/cpu-probe.c +++ b/trunk/arch/mips/kernel/cpu-probe.c @@ -25,8 +25,6 @@ #include #include #include -#include - /* * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, * the implementation of the "wait" feature differs between CPU families. This @@ -183,13 +181,12 @@ void __init check_wait(void) case CPU_5KC: case CPU_25KF: case CPU_PR4450: - case CPU_BMIPS3300: - case CPU_BMIPS4350: - case CPU_BMIPS4380: - case CPU_BMIPS5000: + case CPU_BCM3302: + case CPU_BCM6338: + case CPU_BCM6348: + case CPU_BCM6358: case CPU_CAVIUM_OCTEON: case CPU_CAVIUM_OCTEON_PLUS: - case CPU_CAVIUM_OCTEON2: case CPU_JZRISC: cpu_wait = r4k_wait; break; @@ -905,37 +902,33 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) { decode_configs(c); switch (c->processor_id & 0xff00) { - case PRID_IMP_BMIPS32: - c->cputype = CPU_BMIPS32; - __cpu_name[cpu] = "Broadcom BMIPS32"; - break; - case PRID_IMP_BMIPS3300: - case PRID_IMP_BMIPS3300_ALT: - case PRID_IMP_BMIPS3300_BUG: - c->cputype = CPU_BMIPS3300; - __cpu_name[cpu] = "Broadcom BMIPS3300"; - break; - case PRID_IMP_BMIPS43XX: { - int rev = c->processor_id & 0xff; - - if (rev >= PRID_REV_BMIPS4380_LO && - rev <= PRID_REV_BMIPS4380_HI) { - c->cputype = CPU_BMIPS4380; - __cpu_name[cpu] = "Broadcom BMIPS4380"; - } else { - c->cputype = CPU_BMIPS4350; - __cpu_name[cpu] = "Broadcom BMIPS4350"; - } + case PRID_IMP_BCM3302: + /* same as PRID_IMP_BCM6338 */ + c->cputype = CPU_BCM3302; + __cpu_name[cpu] = "Broadcom BCM3302"; break; - } - case PRID_IMP_BMIPS5000: - c->cputype = CPU_BMIPS5000; - __cpu_name[cpu] = "Broadcom BMIPS5000"; - c->options |= MIPS_CPU_ULRI; + case PRID_IMP_BCM4710: + c->cputype = CPU_BCM4710; + __cpu_name[cpu] = "Broadcom BCM4710"; break; - case PRID_IMP_BMIPS4KC: - c->cputype = CPU_4KC; - __cpu_name[cpu] = "MIPS 4Kc"; + case PRID_IMP_BCM6345: + c->cputype = CPU_BCM6345; + __cpu_name[cpu] = "Broadcom BCM6345"; + break; + case PRID_IMP_BCM6348: + c->cputype = CPU_BCM6348; + __cpu_name[cpu] = "Broadcom BCM6348"; + break; + case PRID_IMP_BCM4350: + switch (c->processor_id & 0xf0) { + case PRID_REV_BCM6358: + c->cputype = CPU_BCM6358; + __cpu_name[cpu] = "Broadcom BCM6358"; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } break; } } @@ -960,12 +953,6 @@ static inline void cpu_probe_cavium(struct cpuinfo_mips *c, unsigned int cpu) if (cpu == 0) __elf_platform = "octeon"; break; - case PRID_IMP_CAVIUM_CN63XX: - c->cputype = CPU_CAVIUM_OCTEON2; - __cpu_name[cpu] = "Cavium Octeon II"; - if (cpu == 0) - __elf_platform = "octeon2"; - break; default: printk(KERN_INFO "Unknown Octeon chip!\n"); c->cputype = CPU_UNKNOWN; @@ -989,12 +976,6 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu) } } -#ifdef CONFIG_64BIT -/* For use by uaccess.h */ -u64 __ua_limit; -EXPORT_SYMBOL(__ua_limit); -#endif - const char *__cpu_name[NR_CPUS]; const char *__elf_platform; @@ -1072,11 +1053,6 @@ __cpuinit void cpu_probe(void) c->srsets = 1; cpu_probe_vmbits(c); - -#ifdef CONFIG_64BIT - if (cpu == 0) - __ua_limit = ~((1ull << cpu_vmbits) - 1); -#endif } __cpuinit void cpu_report(void) diff --git a/trunk/arch/mips/kernel/irq.c b/trunk/arch/mips/kernel/irq.c index 4f93db58a79e..c6345f579a8a 100644 --- a/trunk/arch/mips/kernel/irq.c +++ b/trunk/arch/mips/kernel/irq.c @@ -151,29 +151,6 @@ void __init init_IRQ(void) #endif } -#ifdef DEBUG_STACKOVERFLOW -static inline void check_stack_overflow(void) -{ - unsigned long sp; - - __asm__ __volatile__("move %0, $sp" : "=r" (sp)); - sp &= THREAD_MASK; - - /* - * Check for stack overflow: is there less than STACK_WARN free? - * STACK_WARN is defined as 1/8 of THREAD_SIZE by default. - */ - if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) { - printk("do_IRQ: stack overflow: %ld\n", - sp - sizeof(struct thread_info)); - dump_stack(); - } -} -#else -static inline void check_stack_overflow(void) {} -#endif - - /* * do_IRQ handles all normal device IRQ's (the special * SMP cross-CPU interrupts have their own specific @@ -182,7 +159,6 @@ static inline void check_stack_overflow(void) {} void __irq_entry do_IRQ(unsigned int irq) { irq_enter(); - check_stack_overflow(); __DO_IRQ_SMTC_HOOK(irq); generic_handle_irq(irq); irq_exit(); diff --git a/trunk/arch/mips/kernel/perf_event.c b/trunk/arch/mips/kernel/perf_event.c deleted file mode 100644 index 2b7f3f703b83..000000000000 --- a/trunk/arch/mips/kernel/perf_event.c +++ /dev/null @@ -1,601 +0,0 @@ -/* - * Linux performance counter support for MIPS. - * - * Copyright (C) 2010 MIPS Technologies, Inc. - * Author: Deng-Cheng Zhu - * - * This code is based on the implementation for ARM, which is in turn - * based on the sparc64 perf event code and the x86 code. Performance - * counter access is based on the MIPS Oprofile code. And the callchain - * support references the code of MIPS stacktrace.c. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include /* For perf_irq */ - -/* These are for 32bit counters. For 64bit ones, define them accordingly. */ -#define MAX_PERIOD ((1ULL << 32) - 1) -#define VALID_COUNT 0x7fffffff -#define TOTAL_BITS 32 -#define HIGHEST_BIT 31 - -#define MIPS_MAX_HWEVENTS 4 - -struct cpu_hw_events { - /* Array of events on this cpu. */ - struct perf_event *events[MIPS_MAX_HWEVENTS]; - - /* - * Set the bit (indexed by the counter number) when the counter - * is used for an event. - */ - unsigned long used_mask[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)]; - - /* - * The borrowed MSB for the performance counter. A MIPS performance - * counter uses its bit 31 (for 32bit counters) or bit 63 (for 64bit - * counters) as a factor of determining whether a counter overflow - * should be signaled. So here we use a separate MSB for each - * counter to make things easy. - */ - unsigned long msbs[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)]; - - /* - * Software copy of the control register for each performance counter. - * MIPS CPUs vary in performance counters. They use this differently, - * and even may not use it. - */ - unsigned int saved_ctrl[MIPS_MAX_HWEVENTS]; -}; -DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { - .saved_ctrl = {0}, -}; - -/* The description of MIPS performance events. */ -struct mips_perf_event { - unsigned int event_id; - /* - * MIPS performance counters are indexed starting from 0. - * CNTR_EVEN indicates the indexes of the counters to be used are - * even numbers. - */ - unsigned int cntr_mask; - #define CNTR_EVEN 0x55555555 - #define CNTR_ODD 0xaaaaaaaa -#ifdef CONFIG_MIPS_MT_SMP - enum { - T = 0, - V = 1, - P = 2, - } range; -#else - #define T - #define V - #define P -#endif -}; - -static struct mips_perf_event raw_event; -static DEFINE_MUTEX(raw_event_mutex); - -#define UNSUPPORTED_PERF_EVENT_ID 0xffffffff -#define C(x) PERF_COUNT_HW_CACHE_##x - -struct mips_pmu { - const char *name; - int irq; - irqreturn_t (*handle_irq)(int irq, void *dev); - int (*handle_shared_irq)(void); - void (*start)(void); - void (*stop)(void); - int (*alloc_counter)(struct cpu_hw_events *cpuc, - struct hw_perf_event *hwc); - u64 (*read_counter)(unsigned int idx); - void (*write_counter)(unsigned int idx, u64 val); - void (*enable_event)(struct hw_perf_event *evt, int idx); - void (*disable_event)(int idx); - const struct mips_perf_event *(*map_raw_event)(u64 config); - const struct mips_perf_event (*general_event_map)[PERF_COUNT_HW_MAX]; - const struct mips_perf_event (*cache_event_map) - [PERF_COUNT_HW_CACHE_MAX] - [PERF_COUNT_HW_CACHE_OP_MAX] - [PERF_COUNT_HW_CACHE_RESULT_MAX]; - unsigned int num_counters; -}; - -static const struct mips_pmu *mipspmu; - -static int -mipspmu_event_set_period(struct perf_event *event, - struct hw_perf_event *hwc, - int idx) -{ - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - s64 left = local64_read(&hwc->period_left); - s64 period = hwc->sample_period; - int ret = 0; - u64 uleft; - unsigned long flags; - - if (unlikely(left <= -period)) { - left = period; - local64_set(&hwc->period_left, left); - hwc->last_period = period; - ret = 1; - } - - if (unlikely(left <= 0)) { - left += period; - local64_set(&hwc->period_left, left); - hwc->last_period = period; - ret = 1; - } - - if (left > (s64)MAX_PERIOD) - left = MAX_PERIOD; - - local64_set(&hwc->prev_count, (u64)-left); - - local_irq_save(flags); - uleft = (u64)(-left) & MAX_PERIOD; - uleft > VALID_COUNT ? - set_bit(idx, cpuc->msbs) : clear_bit(idx, cpuc->msbs); - mipspmu->write_counter(idx, (u64)(-left) & VALID_COUNT); - local_irq_restore(flags); - - perf_event_update_userpage(event); - - return ret; -} - -static int mipspmu_enable(struct perf_event *event) -{ - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - struct hw_perf_event *hwc = &event->hw; - int idx; - int err = 0; - - /* To look for a free counter for this event. */ - idx = mipspmu->alloc_counter(cpuc, hwc); - if (idx < 0) { - err = idx; - goto out; - } - - /* - * If there is an event in the counter we are going to use then - * make sure it is disabled. - */ - event->hw.idx = idx; - mipspmu->disable_event(idx); - cpuc->events[idx] = event; - - /* Set the period for the event. */ - mipspmu_event_set_period(event, hwc, idx); - - /* Enable the event. */ - mipspmu->enable_event(hwc, idx); - - /* Propagate our changes to the userspace mapping. */ - perf_event_update_userpage(event); - -out: - return err; -} - -static void mipspmu_event_update(struct perf_event *event, - struct hw_perf_event *hwc, - int idx) -{ - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - unsigned long flags; - int shift = 64 - TOTAL_BITS; - s64 prev_raw_count, new_raw_count; - s64 delta; - -again: - prev_raw_count = local64_read(&hwc->prev_count); - local_irq_save(flags); - /* Make the counter value be a "real" one. */ - new_raw_count = mipspmu->read_counter(idx); - if (new_raw_count & (test_bit(idx, cpuc->msbs) << HIGHEST_BIT)) { - new_raw_count &= VALID_COUNT; - clear_bit(idx, cpuc->msbs); - } else - new_raw_count |= (test_bit(idx, cpuc->msbs) << HIGHEST_BIT); - local_irq_restore(flags); - - if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, - new_raw_count) != prev_raw_count) - goto again; - - delta = (new_raw_count << shift) - (prev_raw_count << shift); - delta >>= shift; - - local64_add(delta, &event->count); - local64_sub(delta, &hwc->period_left); - - return; -} - -static void mipspmu_disable(struct perf_event *event) -{ - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - struct hw_perf_event *hwc = &event->hw; - int idx = hwc->idx; - - - WARN_ON(idx < 0 || idx >= mipspmu->num_counters); - - /* We are working on a local event. */ - mipspmu->disable_event(idx); - - barrier(); - - mipspmu_event_update(event, hwc, idx); - cpuc->events[idx] = NULL; - clear_bit(idx, cpuc->used_mask); - - perf_event_update_userpage(event); -} - -static void mipspmu_unthrottle(struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - - mipspmu->enable_event(hwc, hwc->idx); -} - -static void mipspmu_read(struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - - /* Don't read disabled counters! */ - if (hwc->idx < 0) - return; - - mipspmu_event_update(event, hwc, hwc->idx); -} - -static struct pmu pmu = { - .enable = mipspmu_enable, - .disable = mipspmu_disable, - .unthrottle = mipspmu_unthrottle, - .read = mipspmu_read, -}; - -static atomic_t active_events = ATOMIC_INIT(0); -static DEFINE_MUTEX(pmu_reserve_mutex); -static int (*save_perf_irq)(void); - -static int mipspmu_get_irq(void) -{ - int err; - - if (mipspmu->irq >= 0) { - /* Request my own irq handler. */ - err = request_irq(mipspmu->irq, mipspmu->handle_irq, - IRQF_DISABLED | IRQF_NOBALANCING, - "mips_perf_pmu", NULL); - if (err) { - pr_warning("Unable to request IRQ%d for MIPS " - "performance counters!\n", mipspmu->irq); - } - } else if (cp0_perfcount_irq < 0) { - /* - * We are sharing the irq number with the timer interrupt. - */ - save_perf_irq = perf_irq; - perf_irq = mipspmu->handle_shared_irq; - err = 0; - } else { - pr_warning("The platform hasn't properly defined its " - "interrupt controller.\n"); - err = -ENOENT; - } - - return err; -} - -static void mipspmu_free_irq(void) -{ - if (mipspmu->irq >= 0) - free_irq(mipspmu->irq, NULL); - else if (cp0_perfcount_irq < 0) - perf_irq = save_perf_irq; -} - -static inline unsigned int -mipspmu_perf_event_encode(const struct mips_perf_event *pev) -{ -/* - * Top 8 bits for range, next 16 bits for cntr_mask, lowest 8 bits for - * event_id. - */ -#ifdef CONFIG_MIPS_MT_SMP - return ((unsigned int)pev->range << 24) | - (pev->cntr_mask & 0xffff00) | - (pev->event_id & 0xff); -#else - return (pev->cntr_mask & 0xffff00) | - (pev->event_id & 0xff); -#endif -} - -static const struct mips_perf_event * -mipspmu_map_general_event(int idx) -{ - const struct mips_perf_event *pev; - - pev = ((*mipspmu->general_event_map)[idx].event_id == - UNSUPPORTED_PERF_EVENT_ID ? ERR_PTR(-EOPNOTSUPP) : - &(*mipspmu->general_event_map)[idx]); - - return pev; -} - -static const struct mips_perf_event * -mipspmu_map_cache_event(u64 config) -{ - unsigned int cache_type, cache_op, cache_result; - const struct mips_perf_event *pev; - - cache_type = (config >> 0) & 0xff; - if (cache_type >= PERF_COUNT_HW_CACHE_MAX) - return ERR_PTR(-EINVAL); - - cache_op = (config >> 8) & 0xff; - if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX) - return ERR_PTR(-EINVAL); - - cache_result = (config >> 16) & 0xff; - if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX) - return ERR_PTR(-EINVAL); - - pev = &((*mipspmu->cache_event_map) - [cache_type] - [cache_op] - [cache_result]); - - if (pev->event_id == UNSUPPORTED_PERF_EVENT_ID) - return ERR_PTR(-EOPNOTSUPP); - - return pev; - -} - -static int validate_event(struct cpu_hw_events *cpuc, - struct perf_event *event) -{ - struct hw_perf_event fake_hwc = event->hw; - - if (event->pmu && event->pmu != &pmu) - return 0; - - return mipspmu->alloc_counter(cpuc, &fake_hwc) >= 0; -} - -static int validate_group(struct perf_event *event) -{ - struct perf_event *sibling, *leader = event->group_leader; - struct cpu_hw_events fake_cpuc; - - memset(&fake_cpuc, 0, sizeof(fake_cpuc)); - - if (!validate_event(&fake_cpuc, leader)) - return -ENOSPC; - - list_for_each_entry(sibling, &leader->sibling_list, group_entry) { - if (!validate_event(&fake_cpuc, sibling)) - return -ENOSPC; - } - - if (!validate_event(&fake_cpuc, event)) - return -ENOSPC; - - return 0; -} - -/* - * mipsxx/rm9000/loongson2 have different performance counters, they have - * specific low-level init routines. - */ -static void reset_counters(void *arg); -static int __hw_perf_event_init(struct perf_event *event); - -static void hw_perf_event_destroy(struct perf_event *event) -{ - if (atomic_dec_and_mutex_lock(&active_events, - &pmu_reserve_mutex)) { - /* - * We must not call the destroy function with interrupts - * disabled. - */ - on_each_cpu(reset_counters, - (void *)(long)mipspmu->num_counters, 1); - mipspmu_free_irq(); - mutex_unlock(&pmu_reserve_mutex); - } -} - -const struct pmu *hw_perf_event_init(struct perf_event *event) -{ - int err = 0; - - if (!mipspmu || event->cpu >= nr_cpumask_bits || - (event->cpu >= 0 && !cpu_online(event->cpu))) - return ERR_PTR(-ENODEV); - - if (!atomic_inc_not_zero(&active_events)) { - if (atomic_read(&active_events) > MIPS_MAX_HWEVENTS) { - atomic_dec(&active_events); - return ERR_PTR(-ENOSPC); - } - - mutex_lock(&pmu_reserve_mutex); - if (atomic_read(&active_events) == 0) - err = mipspmu_get_irq(); - - if (!err) - atomic_inc(&active_events); - mutex_unlock(&pmu_reserve_mutex); - } - - if (err) - return ERR_PTR(err); - - err = __hw_perf_event_init(event); - if (err) - hw_perf_event_destroy(event); - - return err ? ERR_PTR(err) : &pmu; -} - -void hw_perf_enable(void) -{ - if (mipspmu) - mipspmu->start(); -} - -void hw_perf_disable(void) -{ - if (mipspmu) - mipspmu->stop(); -} - -/* This is needed by specific irq handlers in perf_event_*.c */ -static void -handle_associated_event(struct cpu_hw_events *cpuc, - int idx, struct perf_sample_data *data, struct pt_regs *regs) -{ - struct perf_event *event = cpuc->events[idx]; - struct hw_perf_event *hwc = &event->hw; - - mipspmu_event_update(event, hwc, idx); - data->period = event->hw.last_period; - if (!mipspmu_event_set_period(event, hwc, idx)) - return; - - if (perf_event_overflow(event, 0, data, regs)) - mipspmu->disable_event(idx); -} - -#include "perf_event_mipsxx.c" - -/* Callchain handling code. */ -static inline void -callchain_store(struct perf_callchain_entry *entry, - u64 ip) -{ - if (entry->nr < PERF_MAX_STACK_DEPTH) - entry->ip[entry->nr++] = ip; -} - -/* - * Leave userspace callchain empty for now. When we find a way to trace - * the user stack callchains, we add here. - */ -static void -perf_callchain_user(struct pt_regs *regs, - struct perf_callchain_entry *entry) -{ -} - -static void save_raw_perf_callchain(struct perf_callchain_entry *entry, - unsigned long reg29) -{ - unsigned long *sp = (unsigned long *)reg29; - unsigned long addr; - - while (!kstack_end(sp)) { - addr = *sp++; - if (__kernel_text_address(addr)) { - callchain_store(entry, addr); - if (entry->nr >= PERF_MAX_STACK_DEPTH) - break; - } - } -} - -static void -perf_callchain_kernel(struct pt_regs *regs, - struct perf_callchain_entry *entry) -{ - unsigned long sp = regs->regs[29]; -#ifdef CONFIG_KALLSYMS - unsigned long ra = regs->regs[31]; - unsigned long pc = regs->cp0_epc; - - callchain_store(entry, PERF_CONTEXT_KERNEL); - if (raw_show_trace || !__kernel_text_address(pc)) { - unsigned long stack_page = - (unsigned long)task_stack_page(current); - if (stack_page && sp >= stack_page && - sp <= stack_page + THREAD_SIZE - 32) - save_raw_perf_callchain(entry, sp); - return; - } - do { - callchain_store(entry, pc); - if (entry->nr >= PERF_MAX_STACK_DEPTH) - break; - pc = unwind_stack(current, &sp, pc, &ra); - } while (pc); -#else - callchain_store(entry, PERF_CONTEXT_KERNEL); - save_raw_perf_callchain(entry, sp); -#endif -} - -static void -perf_do_callchain(struct pt_regs *regs, - struct perf_callchain_entry *entry) -{ - int is_user; - - if (!regs) - return; - - is_user = user_mode(regs); - - if (!current || !current->pid) - return; - - if (is_user && current->state != TASK_RUNNING) - return; - - if (!is_user) { - perf_callchain_kernel(regs, entry); - if (current->mm) - regs = task_pt_regs(current); - else - regs = NULL; - } - if (regs) - perf_callchain_user(regs, entry); -} - -static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry); - -struct perf_callchain_entry * -perf_callchain(struct pt_regs *regs) -{ - struct perf_callchain_entry *entry = &__get_cpu_var(pmc_irq_entry); - - entry->nr = 0; - perf_do_callchain(regs, entry); - return entry; -} diff --git a/trunk/arch/mips/kernel/perf_event_mipsxx.c b/trunk/arch/mips/kernel/perf_event_mipsxx.c deleted file mode 100644 index 5c7c6fc07565..000000000000 --- a/trunk/arch/mips/kernel/perf_event_mipsxx.c +++ /dev/null @@ -1,1052 +0,0 @@ -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) || \ - defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_SB1) - -#define M_CONFIG1_PC (1 << 4) - -#define M_PERFCTL_EXL (1UL << 0) -#define M_PERFCTL_KERNEL (1UL << 1) -#define M_PERFCTL_SUPERVISOR (1UL << 2) -#define M_PERFCTL_USER (1UL << 3) -#define M_PERFCTL_INTERRUPT_ENABLE (1UL << 4) -#define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5) -#define M_PERFCTL_VPEID(vpe) ((vpe) << 16) -#define M_PERFCTL_MT_EN(filter) ((filter) << 20) -#define M_TC_EN_ALL M_PERFCTL_MT_EN(0) -#define M_TC_EN_VPE M_PERFCTL_MT_EN(1) -#define M_TC_EN_TC M_PERFCTL_MT_EN(2) -#define M_PERFCTL_TCID(tcid) ((tcid) << 22) -#define M_PERFCTL_WIDE (1UL << 30) -#define M_PERFCTL_MORE (1UL << 31) - -#define M_PERFCTL_COUNT_EVENT_WHENEVER (M_PERFCTL_EXL | \ - M_PERFCTL_KERNEL | \ - M_PERFCTL_USER | \ - M_PERFCTL_SUPERVISOR | \ - M_PERFCTL_INTERRUPT_ENABLE) - -#ifdef CONFIG_MIPS_MT_SMP -#define M_PERFCTL_CONFIG_MASK 0x3fff801f -#else -#define M_PERFCTL_CONFIG_MASK 0x1f -#endif -#define M_PERFCTL_EVENT_MASK 0xfe0 - -#define M_COUNTER_OVERFLOW (1UL << 31) - -#ifdef CONFIG_MIPS_MT_SMP -static int cpu_has_mipsmt_pertccounters; - -/* - * FIXME: For VSMP, vpe_id() is redefined for Perf-events, because - * cpu_data[cpuid].vpe_id reports 0 for _both_ CPUs. - */ -#if defined(CONFIG_HW_PERF_EVENTS) -#define vpe_id() (cpu_has_mipsmt_pertccounters ? \ - 0 : smp_processor_id()) -#else -#define vpe_id() (cpu_has_mipsmt_pertccounters ? \ - 0 : cpu_data[smp_processor_id()].vpe_id) -#endif - -/* Copied from op_model_mipsxx.c */ -static inline unsigned int vpe_shift(void) -{ - if (num_possible_cpus() > 1) - return 1; - - return 0; -} -#else /* !CONFIG_MIPS_MT_SMP */ -#define vpe_id() 0 - -static inline unsigned int vpe_shift(void) -{ - return 0; -} -#endif /* CONFIG_MIPS_MT_SMP */ - -static inline unsigned int -counters_total_to_per_cpu(unsigned int counters) -{ - return counters >> vpe_shift(); -} - -static inline unsigned int -counters_per_cpu_to_total(unsigned int counters) -{ - return counters << vpe_shift(); -} - -#define __define_perf_accessors(r, n, np) \ - \ -static inline unsigned int r_c0_ ## r ## n(void) \ -{ \ - unsigned int cpu = vpe_id(); \ - \ - switch (cpu) { \ - case 0: \ - return read_c0_ ## r ## n(); \ - case 1: \ - return read_c0_ ## r ## np(); \ - default: \ - BUG(); \ - } \ - return 0; \ -} \ - \ -static inline void w_c0_ ## r ## n(unsigned int value) \ -{ \ - unsigned int cpu = vpe_id(); \ - \ - switch (cpu) { \ - case 0: \ - write_c0_ ## r ## n(value); \ - return; \ - case 1: \ - write_c0_ ## r ## np(value); \ - return; \ - default: \ - BUG(); \ - } \ - return; \ -} \ - -__define_perf_accessors(perfcntr, 0, 2) -__define_perf_accessors(perfcntr, 1, 3) -__define_perf_accessors(perfcntr, 2, 0) -__define_perf_accessors(perfcntr, 3, 1) - -__define_perf_accessors(perfctrl, 0, 2) -__define_perf_accessors(perfctrl, 1, 3) -__define_perf_accessors(perfctrl, 2, 0) -__define_perf_accessors(perfctrl, 3, 1) - -static inline int __n_counters(void) -{ - if (!(read_c0_config1() & M_CONFIG1_PC)) - return 0; - if (!(read_c0_perfctrl0() & M_PERFCTL_MORE)) - return 1; - if (!(read_c0_perfctrl1() & M_PERFCTL_MORE)) - return 2; - if (!(read_c0_perfctrl2() & M_PERFCTL_MORE)) - return 3; - - return 4; -} - -static inline int n_counters(void) -{ - int counters; - - switch (current_cpu_type()) { - case CPU_R10000: - counters = 2; - break; - - case CPU_R12000: - case CPU_R14000: - counters = 4; - break; - - default: - counters = __n_counters(); - } - - return counters; -} - -static void reset_counters(void *arg) -{ - int counters = (int)(long)arg; - switch (counters) { - case 4: - w_c0_perfctrl3(0); - w_c0_perfcntr3(0); - case 3: - w_c0_perfctrl2(0); - w_c0_perfcntr2(0); - case 2: - w_c0_perfctrl1(0); - w_c0_perfcntr1(0); - case 1: - w_c0_perfctrl0(0); - w_c0_perfcntr0(0); - } -} - -static inline u64 -mipsxx_pmu_read_counter(unsigned int idx) -{ - switch (idx) { - case 0: - return r_c0_perfcntr0(); - case 1: - return r_c0_perfcntr1(); - case 2: - return r_c0_perfcntr2(); - case 3: - return r_c0_perfcntr3(); - default: - WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx); - return 0; - } -} - -static inline void -mipsxx_pmu_write_counter(unsigned int idx, u64 val) -{ - switch (idx) { - case 0: - w_c0_perfcntr0(val); - return; - case 1: - w_c0_perfcntr1(val); - return; - case 2: - w_c0_perfcntr2(val); - return; - case 3: - w_c0_perfcntr3(val); - return; - } -} - -static inline unsigned int -mipsxx_pmu_read_control(unsigned int idx) -{ - switch (idx) { - case 0: - return r_c0_perfctrl0(); - case 1: - return r_c0_perfctrl1(); - case 2: - return r_c0_perfctrl2(); - case 3: - return r_c0_perfctrl3(); - default: - WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx); - return 0; - } -} - -static inline void -mipsxx_pmu_write_control(unsigned int idx, unsigned int val) -{ - switch (idx) { - case 0: - w_c0_perfctrl0(val); - return; - case 1: - w_c0_perfctrl1(val); - return; - case 2: - w_c0_perfctrl2(val); - return; - case 3: - w_c0_perfctrl3(val); - return; - } -} - -#ifdef CONFIG_MIPS_MT_SMP -static DEFINE_RWLOCK(pmuint_rwlock); -#endif - -/* 24K/34K/1004K cores can share the same event map. */ -static const struct mips_perf_event mipsxxcore_event_map - [PERF_COUNT_HW_MAX] = { - [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN | CNTR_ODD, P }, - [PERF_COUNT_HW_INSTRUCTIONS] = { 0x01, CNTR_EVEN | CNTR_ODD, T }, - [PERF_COUNT_HW_CACHE_REFERENCES] = { UNSUPPORTED_PERF_EVENT_ID }, - [PERF_COUNT_HW_CACHE_MISSES] = { UNSUPPORTED_PERF_EVENT_ID }, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x02, CNTR_EVEN, T }, - [PERF_COUNT_HW_BRANCH_MISSES] = { 0x02, CNTR_ODD, T }, - [PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID }, -}; - -/* 74K core has different branch event code. */ -static const struct mips_perf_event mipsxx74Kcore_event_map - [PERF_COUNT_HW_MAX] = { - [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN | CNTR_ODD, P }, - [PERF_COUNT_HW_INSTRUCTIONS] = { 0x01, CNTR_EVEN | CNTR_ODD, T }, - [PERF_COUNT_HW_CACHE_REFERENCES] = { UNSUPPORTED_PERF_EVENT_ID }, - [PERF_COUNT_HW_CACHE_MISSES] = { UNSUPPORTED_PERF_EVENT_ID }, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x27, CNTR_EVEN, T }, - [PERF_COUNT_HW_BRANCH_MISSES] = { 0x27, CNTR_ODD, T }, - [PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID }, -}; - -/* 24K/34K/1004K cores can share the same cache event map. */ -static const struct mips_perf_event mipsxxcore_cache_map - [PERF_COUNT_HW_CACHE_MAX] - [PERF_COUNT_HW_CACHE_OP_MAX] - [PERF_COUNT_HW_CACHE_RESULT_MAX] = { -[C(L1D)] = { - /* - * Like some other architectures (e.g. ARM), the performance - * counters don't differentiate between read and write - * accesses/misses, so this isn't strictly correct, but it's the - * best we can do. Writes and reads get combined. - */ - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x0a, CNTR_EVEN, T }, - [C(RESULT_MISS)] = { 0x0b, CNTR_EVEN | CNTR_ODD, T }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { 0x0a, CNTR_EVEN, T }, - [C(RESULT_MISS)] = { 0x0b, CNTR_EVEN | CNTR_ODD, T }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, - [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, - }, -}, -[C(L1I)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x09, CNTR_EVEN, T }, - [C(RESULT_MISS)] = { 0x09, CNTR_ODD, T }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { 0x09, CNTR_EVEN, T }, - [C(RESULT_MISS)] = { 0x09, CNTR_ODD, T }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { 0x14, CNTR_EVEN, T }, - /* - * Note that MIPS has only "hit" events countable for - * the prefetch operation. - */ - [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, - }, -}, -[C(LL)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x15, CNTR_ODD, P }, - [C(RESULT_MISS)] = { 0x16, CNTR_EVEN, P }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { 0x15, CNTR_ODD, P }, - [C(RESULT_MISS)] = { 0x16, CNTR_EVEN, P }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, - [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, - }, -}, -[C(DTLB)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x06, CNTR_EVEN, T }, - [C(RESULT_MISS)] = { 0x06, CNTR_ODD, T }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { 0x06, CNTR_EVEN, T }, - [C(RESULT_MISS)] = { 0x06, CNTR_ODD, T }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, - [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, - }, -}, -[C(ITLB)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x05, CNTR_EVEN, T }, - [C(RESULT_MISS)] = { 0x05, CNTR_ODD, T }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { 0x05, CNTR_EVEN, T }, - [C(RESULT_MISS)] = { 0x05, CNTR_ODD, T }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, - [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, - }, -}, -[C(BPU)] = { - /* Using the same code for *HW_BRANCH* */ - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x02, CNTR_EVEN, T }, - [C(RESULT_MISS)] = { 0x02, CNTR_ODD, T }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { 0x02, CNTR_EVEN, T }, - [C(RESULT_MISS)] = { 0x02, CNTR_ODD, T }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, - [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, - }, -}, -}; - -/* 74K core has completely different cache event map. */ -static const struct mips_perf_event mipsxx74Kcore_cache_map - [PERF_COUNT_HW_CACHE_MAX] - [PERF_COUNT_HW_CACHE_OP_MAX] - [PERF_COUNT_HW_CACHE_RESULT_MAX] = { -[C(L1D)] = { - /* - * Like some other architectures (e.g. ARM), the performance - * counters don't differentiate between read and write - * accesses/misses, so this isn't strictly correct, but it's the - * best we can do. Writes and reads get combined. - */ - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x17, CNTR_ODD, T }, - [C(RESULT_MISS)] = { 0x18, CNTR_ODD, T }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { 0x17, CNTR_ODD, T }, - [C(RESULT_MISS)] = { 0x18, CNTR_ODD, T }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, - [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, - }, -}, -[C(L1I)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x06, CNTR_EVEN, T }, - [C(RESULT_MISS)] = { 0x06, CNTR_ODD, T }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { 0x06, CNTR_EVEN, T }, - [C(RESULT_MISS)] = { 0x06, CNTR_ODD, T }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { 0x34, CNTR_EVEN, T }, - /* - * Note that MIPS has only "hit" events countable for - * the prefetch operation. - */ - [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, - }, -}, -[C(LL)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x1c, CNTR_ODD, P }, - [C(RESULT_MISS)] = { 0x1d, CNTR_EVEN | CNTR_ODD, P }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { 0x1c, CNTR_ODD, P }, - [C(RESULT_MISS)] = { 0x1d, CNTR_EVEN | CNTR_ODD, P }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, - [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, - }, -}, -[C(DTLB)] = { - /* 74K core does not have specific DTLB events. */ - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, - [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, - [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, - [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, - }, -}, -[C(ITLB)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x04, CNTR_EVEN, T }, - [C(RESULT_MISS)] = { 0x04, CNTR_ODD, T }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { 0x04, CNTR_EVEN, T }, - [C(RESULT_MISS)] = { 0x04, CNTR_ODD, T }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, - [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, - }, -}, -[C(BPU)] = { - /* Using the same code for *HW_BRANCH* */ - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = { 0x27, CNTR_EVEN, T }, - [C(RESULT_MISS)] = { 0x27, CNTR_ODD, T }, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = { 0x27, CNTR_EVEN, T }, - [C(RESULT_MISS)] = { 0x27, CNTR_ODD, T }, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, - [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, - }, -}, -}; - -#ifdef CONFIG_MIPS_MT_SMP -static void -check_and_calc_range(struct perf_event *event, - const struct mips_perf_event *pev) -{ - struct hw_perf_event *hwc = &event->hw; - - if (event->cpu >= 0) { - if (pev->range > V) { - /* - * The user selected an event that is processor - * wide, while expecting it to be VPE wide. - */ - hwc->config_base |= M_TC_EN_ALL; - } else { - /* - * FIXME: cpu_data[event->cpu].vpe_id reports 0 - * for both CPUs. - */ - hwc->config_base |= M_PERFCTL_VPEID(event->cpu); - hwc->config_base |= M_TC_EN_VPE; - } - } else - hwc->config_base |= M_TC_EN_ALL; -} -#else -static void -check_and_calc_range(struct perf_event *event, - const struct mips_perf_event *pev) -{ -} -#endif - -static int __hw_perf_event_init(struct perf_event *event) -{ - struct perf_event_attr *attr = &event->attr; - struct hw_perf_event *hwc = &event->hw; - const struct mips_perf_event *pev; - int err; - - /* Returning MIPS event descriptor for generic perf event. */ - if (PERF_TYPE_HARDWARE == event->attr.type) { - if (event->attr.config >= PERF_COUNT_HW_MAX) - return -EINVAL; - pev = mipspmu_map_general_event(event->attr.config); - } else if (PERF_TYPE_HW_CACHE == event->attr.type) { - pev = mipspmu_map_cache_event(event->attr.config); - } else if (PERF_TYPE_RAW == event->attr.type) { - /* We are working on the global raw event. */ - mutex_lock(&raw_event_mutex); - pev = mipspmu->map_raw_event(event->attr.config); - } else { - /* The event type is not (yet) supported. */ - return -EOPNOTSUPP; - } - - if (IS_ERR(pev)) { - if (PERF_TYPE_RAW == event->attr.type) - mutex_unlock(&raw_event_mutex); - return PTR_ERR(pev); - } - - /* - * We allow max flexibility on how each individual counter shared - * by the single CPU operates (the mode exclusion and the range). - */ - hwc->config_base = M_PERFCTL_INTERRUPT_ENABLE; - - /* Calculate range bits and validate it. */ - if (num_possible_cpus() > 1) - check_and_calc_range(event, pev); - - hwc->event_base = mipspmu_perf_event_encode(pev); - if (PERF_TYPE_RAW == event->attr.type) - mutex_unlock(&raw_event_mutex); - - if (!attr->exclude_user) - hwc->config_base |= M_PERFCTL_USER; - if (!attr->exclude_kernel) { - hwc->config_base |= M_PERFCTL_KERNEL; - /* MIPS kernel mode: KSU == 00b || EXL == 1 || ERL == 1 */ - hwc->config_base |= M_PERFCTL_EXL; - } - if (!attr->exclude_hv) - hwc->config_base |= M_PERFCTL_SUPERVISOR; - - hwc->config_base &= M_PERFCTL_CONFIG_MASK; - /* - * The event can belong to another cpu. We do not assign a local - * counter for it for now. - */ - hwc->idx = -1; - hwc->config = 0; - - if (!hwc->sample_period) { - hwc->sample_period = MAX_PERIOD; - hwc->last_period = hwc->sample_period; - local64_set(&hwc->period_left, hwc->sample_period); - } - - err = 0; - if (event->group_leader != event) { - err = validate_group(event); - if (err) - return -EINVAL; - } - - event->destroy = hw_perf_event_destroy; - - return err; -} - -static void pause_local_counters(void) -{ - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - int counters = mipspmu->num_counters; - unsigned long flags; - - local_irq_save(flags); - switch (counters) { - case 4: - cpuc->saved_ctrl[3] = r_c0_perfctrl3(); - w_c0_perfctrl3(cpuc->saved_ctrl[3] & - ~M_PERFCTL_COUNT_EVENT_WHENEVER); - case 3: - cpuc->saved_ctrl[2] = r_c0_perfctrl2(); - w_c0_perfctrl2(cpuc->saved_ctrl[2] & - ~M_PERFCTL_COUNT_EVENT_WHENEVER); - case 2: - cpuc->saved_ctrl[1] = r_c0_perfctrl1(); - w_c0_perfctrl1(cpuc->saved_ctrl[1] & - ~M_PERFCTL_COUNT_EVENT_WHENEVER); - case 1: - cpuc->saved_ctrl[0] = r_c0_perfctrl0(); - w_c0_perfctrl0(cpuc->saved_ctrl[0] & - ~M_PERFCTL_COUNT_EVENT_WHENEVER); - } - local_irq_restore(flags); -} - -static void resume_local_counters(void) -{ - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - int counters = mipspmu->num_counters; - unsigned long flags; - - local_irq_save(flags); - switch (counters) { - case 4: - w_c0_perfctrl3(cpuc->saved_ctrl[3]); - case 3: - w_c0_perfctrl2(cpuc->saved_ctrl[2]); - case 2: - w_c0_perfctrl1(cpuc->saved_ctrl[1]); - case 1: - w_c0_perfctrl0(cpuc->saved_ctrl[0]); - } - local_irq_restore(flags); -} - -static int mipsxx_pmu_handle_shared_irq(void) -{ - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - struct perf_sample_data data; - unsigned int counters = mipspmu->num_counters; - unsigned int counter; - int handled = IRQ_NONE; - struct pt_regs *regs; - - if (cpu_has_mips_r2 && !(read_c0_cause() & (1 << 26))) - return handled; - - /* - * First we pause the local counters, so that when we are locked - * here, the counters are all paused. When it gets locked due to - * perf_disable(), the timer interrupt handler will be delayed. - * - * See also mipsxx_pmu_start(). - */ - pause_local_counters(); -#ifdef CONFIG_MIPS_MT_SMP - read_lock(&pmuint_rwlock); -#endif - - regs = get_irq_regs(); - - perf_sample_data_init(&data, 0); - - switch (counters) { -#define HANDLE_COUNTER(n) \ - case n + 1: \ - if (test_bit(n, cpuc->used_mask)) { \ - counter = r_c0_perfcntr ## n(); \ - if (counter & M_COUNTER_OVERFLOW) { \ - w_c0_perfcntr ## n(counter & \ - VALID_COUNT); \ - if (test_and_change_bit(n, cpuc->msbs)) \ - handle_associated_event(cpuc, \ - n, &data, regs); \ - handled = IRQ_HANDLED; \ - } \ - } - HANDLE_COUNTER(3) - HANDLE_COUNTER(2) - HANDLE_COUNTER(1) - HANDLE_COUNTER(0) - } - - /* - * Do all the work for the pending perf events. We can do this - * in here because the performance counter interrupt is a regular - * interrupt, not NMI. - */ - if (handled == IRQ_HANDLED) - perf_event_do_pending(); - -#ifdef CONFIG_MIPS_MT_SMP - read_unlock(&pmuint_rwlock); -#endif - resume_local_counters(); - return handled; -} - -static irqreturn_t -mipsxx_pmu_handle_irq(int irq, void *dev) -{ - return mipsxx_pmu_handle_shared_irq(); -} - -static void mipsxx_pmu_start(void) -{ -#ifdef CONFIG_MIPS_MT_SMP - write_unlock(&pmuint_rwlock); -#endif - resume_local_counters(); -} - -/* - * MIPS performance counters can be per-TC. The control registers can - * not be directly accessed accross CPUs. Hence if we want to do global - * control, we need cross CPU calls. on_each_cpu() can help us, but we - * can not make sure this function is called with interrupts enabled. So - * here we pause local counters and then grab a rwlock and leave the - * counters on other CPUs alone. If any counter interrupt raises while - * we own the write lock, simply pause local counters on that CPU and - * spin in the handler. Also we know we won't be switched to another - * CPU after pausing local counters and before grabbing the lock. - */ -static void mipsxx_pmu_stop(void) -{ - pause_local_counters(); -#ifdef CONFIG_MIPS_MT_SMP - write_lock(&pmuint_rwlock); -#endif -} - -static int -mipsxx_pmu_alloc_counter(struct cpu_hw_events *cpuc, - struct hw_perf_event *hwc) -{ - int i; - - /* - * We only need to care the counter mask. The range has been - * checked definitely. - */ - unsigned long cntr_mask = (hwc->event_base >> 8) & 0xffff; - - for (i = mipspmu->num_counters - 1; i >= 0; i--) { - /* - * Note that some MIPS perf events can be counted by both - * even and odd counters, wheresas many other are only by - * even _or_ odd counters. This introduces an issue that - * when the former kind of event takes the counter the - * latter kind of event wants to use, then the "counter - * allocation" for the latter event will fail. In fact if - * they can be dynamically swapped, they both feel happy. - * But here we leave this issue alone for now. - */ - if (test_bit(i, &cntr_mask) && - !test_and_set_bit(i, cpuc->used_mask)) - return i; - } - - return -EAGAIN; -} - -static void -mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx) -{ - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - unsigned long flags; - - WARN_ON(idx < 0 || idx >= mipspmu->num_counters); - - local_irq_save(flags); - cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(evt->event_base & 0xff) | - (evt->config_base & M_PERFCTL_CONFIG_MASK) | - /* Make sure interrupt enabled. */ - M_PERFCTL_INTERRUPT_ENABLE; - /* - * We do not actually let the counter run. Leave it until start(). - */ - local_irq_restore(flags); -} - -static void -mipsxx_pmu_disable_event(int idx) -{ - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - unsigned long flags; - - WARN_ON(idx < 0 || idx >= mipspmu->num_counters); - - local_irq_save(flags); - cpuc->saved_ctrl[idx] = mipsxx_pmu_read_control(idx) & - ~M_PERFCTL_COUNT_EVENT_WHENEVER; - mipsxx_pmu_write_control(idx, cpuc->saved_ctrl[idx]); - local_irq_restore(flags); -} - -/* 24K */ -#define IS_UNSUPPORTED_24K_EVENT(r, b) \ - ((b) == 12 || (r) == 151 || (r) == 152 || (b) == 26 || \ - (b) == 27 || (r) == 28 || (r) == 158 || (b) == 31 || \ - (b) == 32 || (b) == 34 || (b) == 36 || (r) == 168 || \ - (r) == 172 || (b) == 47 || ((b) >= 56 && (b) <= 63) || \ - ((b) >= 68 && (b) <= 127)) -#define IS_BOTH_COUNTERS_24K_EVENT(b) \ - ((b) == 0 || (b) == 1 || (b) == 11) - -/* 34K */ -#define IS_UNSUPPORTED_34K_EVENT(r, b) \ - ((b) == 12 || (r) == 27 || (r) == 158 || (b) == 36 || \ - (b) == 38 || (r) == 175 || ((b) >= 56 && (b) <= 63) || \ - ((b) >= 68 && (b) <= 127)) -#define IS_BOTH_COUNTERS_34K_EVENT(b) \ - ((b) == 0 || (b) == 1 || (b) == 11) -#ifdef CONFIG_MIPS_MT_SMP -#define IS_RANGE_P_34K_EVENT(r, b) \ - ((b) == 0 || (r) == 18 || (b) == 21 || (b) == 22 || \ - (b) == 25 || (b) == 39 || (r) == 44 || (r) == 174 || \ - (r) == 176 || ((b) >= 50 && (b) <= 55) || \ - ((b) >= 64 && (b) <= 67)) -#define IS_RANGE_V_34K_EVENT(r) ((r) == 47) -#endif - -/* 74K */ -#define IS_UNSUPPORTED_74K_EVENT(r, b) \ - ((r) == 5 || ((r) >= 135 && (r) <= 137) || \ - ((b) >= 10 && (b) <= 12) || (b) == 22 || (b) == 27 || \ - (b) == 33 || (b) == 34 || ((b) >= 47 && (b) <= 49) || \ - (r) == 178 || (b) == 55 || (b) == 57 || (b) == 60 || \ - (b) == 61 || (r) == 62 || (r) == 191 || \ - ((b) >= 64 && (b) <= 127)) -#define IS_BOTH_COUNTERS_74K_EVENT(b) \ - ((b) == 0 || (b) == 1) - -/* 1004K */ -#define IS_UNSUPPORTED_1004K_EVENT(r, b) \ - ((b) == 12 || (r) == 27 || (r) == 158 || (b) == 38 || \ - (r) == 175 || (b) == 63 || ((b) >= 68 && (b) <= 127)) -#define IS_BOTH_COUNTERS_1004K_EVENT(b) \ - ((b) == 0 || (b) == 1 || (b) == 11) -#ifdef CONFIG_MIPS_MT_SMP -#define IS_RANGE_P_1004K_EVENT(r, b) \ - ((b) == 0 || (r) == 18 || (b) == 21 || (b) == 22 || \ - (b) == 25 || (b) == 36 || (b) == 39 || (r) == 44 || \ - (r) == 174 || (r) == 176 || ((b) >= 50 && (b) <= 59) || \ - (r) == 188 || (b) == 61 || (b) == 62 || \ - ((b) >= 64 && (b) <= 67)) -#define IS_RANGE_V_1004K_EVENT(r) ((r) == 47) -#endif - -/* - * User can use 0-255 raw events, where 0-127 for the events of even - * counters, and 128-255 for odd counters. Note that bit 7 is used to - * indicate the parity. So, for example, when user wants to take the - * Event Num of 15 for odd counters (by referring to the user manual), - * then 128 needs to be added to 15 as the input for the event config, - * i.e., 143 (0x8F) to be used. - */ -static const struct mips_perf_event * -mipsxx_pmu_map_raw_event(u64 config) -{ - unsigned int raw_id = config & 0xff; - unsigned int base_id = raw_id & 0x7f; - - switch (current_cpu_type()) { - case CPU_24K: - if (IS_UNSUPPORTED_24K_EVENT(raw_id, base_id)) - return ERR_PTR(-EOPNOTSUPP); - raw_event.event_id = base_id; - if (IS_BOTH_COUNTERS_24K_EVENT(base_id)) - raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; - else - raw_event.cntr_mask = - raw_id > 127 ? CNTR_ODD : CNTR_EVEN; -#ifdef CONFIG_MIPS_MT_SMP - /* - * This is actually doing nothing. Non-multithreading - * CPUs will not check and calculate the range. - */ - raw_event.range = P; -#endif - break; - case CPU_34K: - if (IS_UNSUPPORTED_34K_EVENT(raw_id, base_id)) - return ERR_PTR(-EOPNOTSUPP); - raw_event.event_id = base_id; - if (IS_BOTH_COUNTERS_34K_EVENT(base_id)) - raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; - else - raw_event.cntr_mask = - raw_id > 127 ? CNTR_ODD : CNTR_EVEN; -#ifdef CONFIG_MIPS_MT_SMP - if (IS_RANGE_P_34K_EVENT(raw_id, base_id)) - raw_event.range = P; - else if (unlikely(IS_RANGE_V_34K_EVENT(raw_id))) - raw_event.range = V; - else - raw_event.range = T; -#endif - break; - case CPU_74K: - if (IS_UNSUPPORTED_74K_EVENT(raw_id, base_id)) - return ERR_PTR(-EOPNOTSUPP); - raw_event.event_id = base_id; - if (IS_BOTH_COUNTERS_74K_EVENT(base_id)) - raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; - else - raw_event.cntr_mask = - raw_id > 127 ? CNTR_ODD : CNTR_EVEN; -#ifdef CONFIG_MIPS_MT_SMP - raw_event.range = P; -#endif - break; - case CPU_1004K: - if (IS_UNSUPPORTED_1004K_EVENT(raw_id, base_id)) - return ERR_PTR(-EOPNOTSUPP); - raw_event.event_id = base_id; - if (IS_BOTH_COUNTERS_1004K_EVENT(base_id)) - raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; - else - raw_event.cntr_mask = - raw_id > 127 ? CNTR_ODD : CNTR_EVEN; -#ifdef CONFIG_MIPS_MT_SMP - if (IS_RANGE_P_1004K_EVENT(raw_id, base_id)) - raw_event.range = P; - else if (unlikely(IS_RANGE_V_1004K_EVENT(raw_id))) - raw_event.range = V; - else - raw_event.range = T; -#endif - break; - } - - return &raw_event; -} - -static struct mips_pmu mipsxxcore_pmu = { - .handle_irq = mipsxx_pmu_handle_irq, - .handle_shared_irq = mipsxx_pmu_handle_shared_irq, - .start = mipsxx_pmu_start, - .stop = mipsxx_pmu_stop, - .alloc_counter = mipsxx_pmu_alloc_counter, - .read_counter = mipsxx_pmu_read_counter, - .write_counter = mipsxx_pmu_write_counter, - .enable_event = mipsxx_pmu_enable_event, - .disable_event = mipsxx_pmu_disable_event, - .map_raw_event = mipsxx_pmu_map_raw_event, - .general_event_map = &mipsxxcore_event_map, - .cache_event_map = &mipsxxcore_cache_map, -}; - -static struct mips_pmu mipsxx74Kcore_pmu = { - .handle_irq = mipsxx_pmu_handle_irq, - .handle_shared_irq = mipsxx_pmu_handle_shared_irq, - .start = mipsxx_pmu_start, - .stop = mipsxx_pmu_stop, - .alloc_counter = mipsxx_pmu_alloc_counter, - .read_counter = mipsxx_pmu_read_counter, - .write_counter = mipsxx_pmu_write_counter, - .enable_event = mipsxx_pmu_enable_event, - .disable_event = mipsxx_pmu_disable_event, - .map_raw_event = mipsxx_pmu_map_raw_event, - .general_event_map = &mipsxx74Kcore_event_map, - .cache_event_map = &mipsxx74Kcore_cache_map, -}; - -static int __init -init_hw_perf_events(void) -{ - int counters, irq; - - pr_info("Performance counters: "); - - counters = n_counters(); - if (counters == 0) { - pr_cont("No available PMU.\n"); - return -ENODEV; - } - -#ifdef CONFIG_MIPS_MT_SMP - cpu_has_mipsmt_pertccounters = read_c0_config7() & (1<<19); - if (!cpu_has_mipsmt_pertccounters) - counters = counters_total_to_per_cpu(counters); -#endif - -#ifdef MSC01E_INT_BASE - if (cpu_has_veic) { - /* - * Using platform specific interrupt controller defines. - */ - irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; - } else { -#endif - if (cp0_perfcount_irq >= 0) - irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; - else - irq = -1; -#ifdef MSC01E_INT_BASE - } -#endif - - on_each_cpu(reset_counters, (void *)(long)counters, 1); - - switch (current_cpu_type()) { - case CPU_24K: - mipsxxcore_pmu.name = "mips/24K"; - mipsxxcore_pmu.num_counters = counters; - mipsxxcore_pmu.irq = irq; - mipspmu = &mipsxxcore_pmu; - break; - case CPU_34K: - mipsxxcore_pmu.name = "mips/34K"; - mipsxxcore_pmu.num_counters = counters; - mipsxxcore_pmu.irq = irq; - mipspmu = &mipsxxcore_pmu; - break; - case CPU_74K: - mipsxx74Kcore_pmu.name = "mips/74K"; - mipsxx74Kcore_pmu.num_counters = counters; - mipsxx74Kcore_pmu.irq = irq; - mipspmu = &mipsxx74Kcore_pmu; - break; - case CPU_1004K: - mipsxxcore_pmu.name = "mips/1004K"; - mipsxxcore_pmu.num_counters = counters; - mipsxxcore_pmu.irq = irq; - mipspmu = &mipsxxcore_pmu; - break; - default: - pr_cont("Either hardware does not support performance " - "counters, or not yet implemented.\n"); - return -ENODEV; - } - - if (mipspmu) - pr_cont("%s PMU enabled, %d counters available to each " - "CPU, irq %d%s\n", mipspmu->name, counters, irq, - irq < 0 ? " (share with timer interrupt)" : ""); - - return 0; -} -arch_initcall(init_hw_perf_events); - -#endif /* defined(CONFIG_CPU_MIPS32)... */ diff --git a/trunk/arch/mips/kernel/setup.c b/trunk/arch/mips/kernel/setup.c index acd3f2c49c06..a6b900f2962b 100644 --- a/trunk/arch/mips/kernel/setup.c +++ b/trunk/arch/mips/kernel/setup.c @@ -490,7 +490,6 @@ static void __init arch_mem_init(char **cmdline_p) bootmem_init(); device_tree_init(); sparse_init(); - plat_swiotlb_setup(); paging_init(); } diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c index 8e9fbe75894e..d053bf4759e4 100644 --- a/trunk/arch/mips/kernel/traps.c +++ b/trunk/arch/mips/kernel/traps.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -577,16 +576,10 @@ static inline int simulate_sc(struct pt_regs *regs, unsigned int opcode) */ static int simulate_llsc(struct pt_regs *regs, unsigned int opcode) { - if ((opcode & OPCODE) == LL) { - perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, - 1, 0, regs, 0); + if ((opcode & OPCODE) == LL) return simulate_ll(regs, opcode); - } - if ((opcode & OPCODE) == SC) { - perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, - 1, 0, regs, 0); + if ((opcode & OPCODE) == SC) return simulate_sc(regs, opcode); - } return -1; /* Must be something else ... */ } @@ -602,8 +595,6 @@ static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode) if ((opcode & OPCODE) == SPEC3 && (opcode & FUNC) == RDHWR) { int rd = (opcode & RD) >> 11; int rt = (opcode & RT) >> 16; - perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, - 1, 0, regs, 0); switch (rd) { case 0: /* CPU number */ regs->regs[rt] = smp_processor_id(); @@ -639,11 +630,8 @@ static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode) static int simulate_sync(struct pt_regs *regs, unsigned int opcode) { - if ((opcode & OPCODE) == SPEC0 && (opcode & FUNC) == SYNC) { - perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, - 1, 0, regs, 0); + if ((opcode & OPCODE) == SPEC0 && (opcode & FUNC) == SYNC) return 0; - } return -1; /* Must be something else ... */ } @@ -1481,7 +1469,6 @@ void __cpuinit per_cpu_trap_init(void) { unsigned int cpu = smp_processor_id(); unsigned int status_set = ST0_CU0; - unsigned int hwrena = cpu_hwrena_impl_bits; #ifdef CONFIG_MIPS_MT_SMTC int secondaryTC = 0; int bootTC = (cpu == 0); @@ -1514,14 +1501,14 @@ void __cpuinit per_cpu_trap_init(void) change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX, status_set); - if (cpu_has_mips_r2) - hwrena |= 0x0000000f; + if (cpu_has_mips_r2) { + unsigned int enable = 0x0000000f | cpu_hwrena_impl_bits; - if (!noulri && cpu_has_userlocal) - hwrena |= (1 << 29); + if (!noulri && cpu_has_userlocal) + enable |= (1 << 29); - if (hwrena) - write_c0_hwrena(hwrena); + write_c0_hwrena(enable); + } #ifdef CONFIG_MIPS_MT_SMTC if (!secondaryTC) { diff --git a/trunk/arch/mips/kernel/unaligned.c b/trunk/arch/mips/kernel/unaligned.c index cfea1adfa153..33d5a5ce4a29 100644 --- a/trunk/arch/mips/kernel/unaligned.c +++ b/trunk/arch/mips/kernel/unaligned.c @@ -78,8 +78,6 @@ #include #include #include -#include - #include #include #include @@ -111,9 +109,6 @@ static void emulate_load_store_insn(struct pt_regs *regs, unsigned long value; unsigned int res; - perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, - 1, 0, regs, 0); - /* * This load never faults. */ @@ -516,8 +511,6 @@ asmlinkage void do_ade(struct pt_regs *regs) unsigned int __user *pc; mm_segment_t seg; - perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, - 1, 0, regs, regs->cp0_badvaddr); /* * Did we catch a fault trying to load an instruction? * Or are we running in MIPS16 mode? diff --git a/trunk/arch/mips/loongson/Kconfig b/trunk/arch/mips/loongson/Kconfig index 6e1b77fec7ea..c97ca69b94e0 100644 --- a/trunk/arch/mips/loongson/Kconfig +++ b/trunk/arch/mips/loongson/Kconfig @@ -20,6 +20,7 @@ config LEMOTE_FULOONG2E select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_HIGHMEM select SYS_HAS_EARLY_PRINTK + select GENERIC_HARDIRQS_NO__DO_IRQ select GENERIC_ISA_DMA_SUPPORT_BROKEN select CPU_HAS_WB select LOONGSON_MC146818 @@ -39,6 +40,7 @@ config LEMOTE_MACH2F select CS5536 select CSRC_R4K if ! MIPS_EXTERNAL_TIMER select DMA_NONCOHERENT + select GENERIC_HARDIRQS_NO__DO_IRQ select GENERIC_ISA_DMA_SUPPORT_BROKEN select HW_HAS_PCI select I8259 diff --git a/trunk/arch/mips/math-emu/cp1emu.c b/trunk/arch/mips/math-emu/cp1emu.c index b2ad1b0910ff..ec3faa413f3b 100644 --- a/trunk/arch/mips/math-emu/cp1emu.c +++ b/trunk/arch/mips/math-emu/cp1emu.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include @@ -259,8 +258,6 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) } emul: - perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, - 1, 0, xcp, 0); MIPS_FPU_EMU_INC_STATS(emulated); switch (MIPSInst_OPCODE(ir)) { case ldc1_op:{ diff --git a/trunk/arch/mips/mm/c-octeon.c b/trunk/arch/mips/mm/c-octeon.c index 16c4d256b76f..0f9c488044d1 100644 --- a/trunk/arch/mips/mm/c-octeon.c +++ b/trunk/arch/mips/mm/c-octeon.c @@ -181,10 +181,10 @@ static void __cpuinit probe_octeon(void) unsigned int config1; struct cpuinfo_mips *c = ¤t_cpu_data; - config1 = read_c0_config1(); switch (c->cputype) { case CPU_CAVIUM_OCTEON: case CPU_CAVIUM_OCTEON_PLUS: + config1 = read_c0_config1(); c->icache.linesz = 2 << ((config1 >> 19) & 7); c->icache.sets = 64 << ((config1 >> 22) & 7); c->icache.ways = 1 + ((config1 >> 16) & 7); @@ -204,20 +204,6 @@ static void __cpuinit probe_octeon(void) c->options |= MIPS_CPU_PREFETCH; break; - case CPU_CAVIUM_OCTEON2: - c->icache.linesz = 2 << ((config1 >> 19) & 7); - c->icache.sets = 8; - c->icache.ways = 37; - c->icache.flags |= MIPS_CACHE_VTAG; - icache_size = c->icache.sets * c->icache.ways * c->icache.linesz; - - c->dcache.linesz = 128; - c->dcache.ways = 32; - c->dcache.sets = 8; - dcache_size = c->dcache.sets * c->dcache.ways * c->dcache.linesz; - c->options |= MIPS_CPU_PREFETCH; - break; - default: panic("Unsupported Cavium Networks CPU type\n"); break; diff --git a/trunk/arch/mips/mm/c-r4k.c b/trunk/arch/mips/mm/c-r4k.c index b4923a75cb4b..6721ee2b1e8b 100644 --- a/trunk/arch/mips/mm/c-r4k.c +++ b/trunk/arch/mips/mm/c-r4k.c @@ -42,14 +42,14 @@ * o collapses to normal function call on UP kernels * o collapses to normal function call on systems with a single shared * primary cache. - * o doesn't disable interrupts on the local CPU */ -static inline void r4k_on_each_cpu(void (*func) (void *info), void *info) +static inline void r4k_on_each_cpu(void (*func) (void *info), void *info, + int wait) { preempt_disable(); #if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC) - smp_call_function(func, info, 1); + smp_call_function(func, info, wait); #endif func(info); preempt_enable(); @@ -363,7 +363,7 @@ static inline void local_r4k___flush_cache_all(void * args) static void r4k___flush_cache_all(void) { - r4k_on_each_cpu(local_r4k___flush_cache_all, NULL); + r4k_on_each_cpu(local_r4k___flush_cache_all, NULL, 1); } static inline int has_valid_asid(const struct mm_struct *mm) @@ -410,7 +410,7 @@ static void r4k_flush_cache_range(struct vm_area_struct *vma, int exec = vma->vm_flags & VM_EXEC; if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) - r4k_on_each_cpu(local_r4k_flush_cache_range, vma); + r4k_on_each_cpu(local_r4k_flush_cache_range, vma, 1); } static inline void local_r4k_flush_cache_mm(void * args) @@ -442,7 +442,7 @@ static void r4k_flush_cache_mm(struct mm_struct *mm) if (!cpu_has_dc_aliases) return; - r4k_on_each_cpu(local_r4k_flush_cache_mm, mm); + r4k_on_each_cpu(local_r4k_flush_cache_mm, mm, 1); } struct flush_cache_page_args { @@ -534,7 +534,7 @@ static void r4k_flush_cache_page(struct vm_area_struct *vma, args.addr = addr; args.pfn = pfn; - r4k_on_each_cpu(local_r4k_flush_cache_page, &args); + r4k_on_each_cpu(local_r4k_flush_cache_page, &args, 1); } static inline void local_r4k_flush_data_cache_page(void * addr) @@ -547,7 +547,8 @@ static void r4k_flush_data_cache_page(unsigned long addr) if (in_atomic()) local_r4k_flush_data_cache_page((void *)addr); else - r4k_on_each_cpu(local_r4k_flush_data_cache_page, (void *) addr); + r4k_on_each_cpu(local_r4k_flush_data_cache_page, (void *) addr, + 1); } struct flush_icache_range_args { @@ -588,7 +589,7 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) args.start = start; args.end = end; - r4k_on_each_cpu(local_r4k_flush_icache_range_ipi, &args); + r4k_on_each_cpu(local_r4k_flush_icache_range_ipi, &args, 1); instruction_hazard(); } @@ -709,7 +710,7 @@ static void local_r4k_flush_cache_sigtramp(void * arg) static void r4k_flush_cache_sigtramp(unsigned long addr) { - r4k_on_each_cpu(local_r4k_flush_cache_sigtramp, (void *) addr); + r4k_on_each_cpu(local_r4k_flush_cache_sigtramp, (void *) addr, 1); } static void r4k_flush_icache_all(void) diff --git a/trunk/arch/mips/mm/dma-default.c b/trunk/arch/mips/mm/dma-default.c index 4fc1a0fbe007..469d4019f795 100644 --- a/trunk/arch/mips/mm/dma-default.c +++ b/trunk/arch/mips/mm/dma-default.c @@ -95,9 +95,10 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size, return ret; } + EXPORT_SYMBOL(dma_alloc_noncoherent); -static void *mips_dma_alloc_coherent(struct device *dev, size_t size, +void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t * dma_handle, gfp_t gfp) { void *ret; @@ -122,6 +123,7 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size, return ret; } +EXPORT_SYMBOL(dma_alloc_coherent); void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle) @@ -129,9 +131,10 @@ void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr, plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL); free_pages((unsigned long) vaddr, get_order(size)); } + EXPORT_SYMBOL(dma_free_noncoherent); -static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, +void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle) { unsigned long addr = (unsigned long) vaddr; @@ -148,6 +151,8 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, free_pages(addr, get_order(size)); } +EXPORT_SYMBOL(dma_free_coherent); + static inline void __dma_sync(unsigned long addr, size_t size, enum dma_data_direction direction) { @@ -169,8 +174,21 @@ static inline void __dma_sync(unsigned long addr, size_t size, } } -static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction direction, struct dma_attrs *attrs) +dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction) +{ + unsigned long addr = (unsigned long) ptr; + + if (!plat_device_is_coherent(dev)) + __dma_sync(addr, size, direction); + + return plat_map_dma_mem(dev, ptr, size); +} + +EXPORT_SYMBOL(dma_map_single); + +void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, + enum dma_data_direction direction) { if (cpu_is_noncoherent_r10000(dev)) __dma_sync(dma_addr_to_virt(dev, dma_addr), size, @@ -179,11 +197,15 @@ static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, plat_unmap_dma_mem(dev, dma_addr, size, direction); } -static int mips_dma_map_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction, struct dma_attrs *attrs) +EXPORT_SYMBOL(dma_unmap_single); + +int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction direction) { int i; + BUG_ON(direction == DMA_NONE); + for (i = 0; i < nents; i++, sg++) { unsigned long addr; @@ -197,27 +219,33 @@ static int mips_dma_map_sg(struct device *dev, struct scatterlist *sg, return nents; } -static dma_addr_t mips_dma_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, enum dma_data_direction direction, - struct dma_attrs *attrs) +EXPORT_SYMBOL(dma_map_sg); + +dma_addr_t dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, enum dma_data_direction direction) { - unsigned long addr; + BUG_ON(direction == DMA_NONE); - addr = (unsigned long) page_address(page) + offset; + if (!plat_device_is_coherent(dev)) { + unsigned long addr; - if (!plat_device_is_coherent(dev)) + addr = (unsigned long) page_address(page) + offset; __dma_sync(addr, size, direction); + } - return plat_map_dma_mem(dev, (void *)addr, size); + return plat_map_dma_mem_page(dev, page) + offset; } -static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sg, - int nhwentries, enum dma_data_direction direction, - struct dma_attrs *attrs) +EXPORT_SYMBOL(dma_map_page); + +void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, + enum dma_data_direction direction) { unsigned long addr; int i; + BUG_ON(direction == DMA_NONE); + for (i = 0; i < nhwentries; i++, sg++) { if (!plat_device_is_coherent(dev) && direction != DMA_TO_DEVICE) { @@ -229,9 +257,13 @@ static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sg, } } -static void mips_dma_sync_single_for_cpu(struct device *dev, - dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) +EXPORT_SYMBOL(dma_unmap_sg); + +void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction) { + BUG_ON(direction == DMA_NONE); + if (cpu_is_noncoherent_r10000(dev)) { unsigned long addr; @@ -240,9 +272,13 @@ static void mips_dma_sync_single_for_cpu(struct device *dev, } } -static void mips_dma_sync_single_for_device(struct device *dev, - dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) +EXPORT_SYMBOL(dma_sync_single_for_cpu); + +void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction) { + BUG_ON(direction == DMA_NONE); + plat_extra_sync_for_device(dev); if (!plat_device_is_coherent(dev)) { unsigned long addr; @@ -252,11 +288,46 @@ static void mips_dma_sync_single_for_device(struct device *dev, } } -static void mips_dma_sync_sg_for_cpu(struct device *dev, - struct scatterlist *sg, int nelems, enum dma_data_direction direction) +EXPORT_SYMBOL(dma_sync_single_for_device); + +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) +{ + BUG_ON(direction == DMA_NONE); + + if (cpu_is_noncoherent_r10000(dev)) { + unsigned long addr; + + addr = dma_addr_to_virt(dev, dma_handle); + __dma_sync(addr + offset, size, direction); + } +} + +EXPORT_SYMBOL(dma_sync_single_range_for_cpu); + +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) +{ + BUG_ON(direction == DMA_NONE); + + plat_extra_sync_for_device(dev); + if (!plat_device_is_coherent(dev)) { + unsigned long addr; + + addr = dma_addr_to_virt(dev, dma_handle); + __dma_sync(addr + offset, size, direction); + } +} + +EXPORT_SYMBOL(dma_sync_single_range_for_device); + +void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction direction) { int i; + BUG_ON(direction == DMA_NONE); + /* Make sure that gcc doesn't leave the empty loop body. */ for (i = 0; i < nelems; i++, sg++) { if (cpu_is_noncoherent_r10000(dev)) @@ -265,11 +336,15 @@ static void mips_dma_sync_sg_for_cpu(struct device *dev, } } -static void mips_dma_sync_sg_for_device(struct device *dev, - struct scatterlist *sg, int nelems, enum dma_data_direction direction) +EXPORT_SYMBOL(dma_sync_sg_for_cpu); + +void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction direction) { int i; + BUG_ON(direction == DMA_NONE); + /* Make sure that gcc doesn't leave the empty loop body. */ for (i = 0; i < nelems; i++, sg++) { if (!plat_device_is_coherent(dev)) @@ -278,18 +353,24 @@ static void mips_dma_sync_sg_for_device(struct device *dev, } } -int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +EXPORT_SYMBOL(dma_sync_sg_for_device); + +int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return plat_dma_mapping_error(dev, dma_addr); } -int mips_dma_supported(struct device *dev, u64 mask) +EXPORT_SYMBOL(dma_mapping_error); + +int dma_supported(struct device *dev, u64 mask) { return plat_dma_supported(dev, mask); } -void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size, - enum dma_data_direction direction) +EXPORT_SYMBOL(dma_supported); + +void dma_cache_sync(struct device *dev, void *vaddr, size_t size, + enum dma_data_direction direction) { BUG_ON(direction == DMA_NONE); @@ -298,30 +379,4 @@ void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size, __dma_sync((unsigned long)vaddr, size, direction); } -static struct dma_map_ops mips_default_dma_map_ops = { - .alloc_coherent = mips_dma_alloc_coherent, - .free_coherent = mips_dma_free_coherent, - .map_page = mips_dma_map_page, - .unmap_page = mips_dma_unmap_page, - .map_sg = mips_dma_map_sg, - .unmap_sg = mips_dma_unmap_sg, - .sync_single_for_cpu = mips_dma_sync_single_for_cpu, - .sync_single_for_device = mips_dma_sync_single_for_device, - .sync_sg_for_cpu = mips_dma_sync_sg_for_cpu, - .sync_sg_for_device = mips_dma_sync_sg_for_device, - .mapping_error = mips_dma_mapping_error, - .dma_supported = mips_dma_supported -}; - -struct dma_map_ops *mips_dma_map_ops = &mips_default_dma_map_ops; -EXPORT_SYMBOL(mips_dma_map_ops); - -#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16) - -static int __init mips_dma_init(void) -{ - dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); - - return 0; -} -fs_initcall(mips_dma_init); +EXPORT_SYMBOL(dma_cache_sync); diff --git a/trunk/arch/mips/mm/fault.c b/trunk/arch/mips/mm/fault.c index 137ee76a0045..783ad0065fdf 100644 --- a/trunk/arch/mips/mm/fault.c +++ b/trunk/arch/mips/mm/fault.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -145,7 +144,6 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long writ * the fault. */ fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0); - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address); if (unlikely(fault & VM_FAULT_ERROR)) { if (fault & VM_FAULT_OOM) goto out_of_memory; @@ -153,15 +151,10 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long writ goto do_sigbus; BUG(); } - if (fault & VM_FAULT_MAJOR) { - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, - 1, 0, regs, address); + if (fault & VM_FAULT_MAJOR) tsk->maj_flt++; - } else { - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, - 1, 0, regs, address); + else tsk->min_flt++; - } up_read(&mm->mmap_sem); return; diff --git a/trunk/arch/mips/mm/sc-mips.c b/trunk/arch/mips/mm/sc-mips.c index 505fecad4684..5ab5fa8c1d82 100644 --- a/trunk/arch/mips/mm/sc-mips.c +++ b/trunk/arch/mips/mm/sc-mips.c @@ -57,34 +57,6 @@ static struct bcache_ops mips_sc_ops = { .bc_inv = mips_sc_inv }; -/* - * Check if the L2 cache controller is activated on a particular platform. - * MTI's L2 controller and the L2 cache controller of Broadcom's BMIPS - * cores both use c0_config2's bit 12 as "L2 Bypass" bit, that is the - * cache being disabled. However there is no guarantee for this to be - * true on all platforms. In an act of stupidity the spec defined bits - * 12..15 as implementation defined so below function will eventually have - * to be replaced by a platform specific probe. - */ -static inline int mips_sc_is_activated(struct cpuinfo_mips *c) -{ - /* Check the bypass bit (L2B) */ - switch (c->cputype) { - case CPU_34K: - case CPU_74K: - case CPU_1004K: - case CPU_BMIPS5000: - if (config2 & (1 << 12)) - return 0; - } - - tmp = (config2 >> 4) & 0x0f; - if (0 < tmp && tmp <= 7) - c->scache.linesz = 2 << tmp; - else - return 0; -} - static inline int __init mips_sc_probe(void) { struct cpuinfo_mips *c = ¤t_cpu_data; @@ -107,8 +79,10 @@ static inline int __init mips_sc_probe(void) return 0; config2 = read_c0_config2(); - - if (!mips_sc_is_activated(c)) + tmp = (config2 >> 4) & 0x0f; + if (0 < tmp && tmp <= 7) + c->scache.linesz = 2 << tmp; + else return 0; tmp = (config2 >> 8) & 0x0f; diff --git a/trunk/arch/mips/mm/tlbex.c b/trunk/arch/mips/mm/tlbex.c index 93816f3bca67..4510e61883eb 100644 --- a/trunk/arch/mips/mm/tlbex.c +++ b/trunk/arch/mips/mm/tlbex.c @@ -338,12 +338,13 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l, case CPU_4KSC: case CPU_20KC: case CPU_25KF: - case CPU_BMIPS32: - case CPU_BMIPS3300: - case CPU_BMIPS4350: - case CPU_BMIPS4380: - case CPU_BMIPS5000: + case CPU_BCM3302: + case CPU_BCM4710: case CPU_LOONGSON2: + case CPU_BCM6338: + case CPU_BCM6345: + case CPU_BCM6348: + case CPU_BCM6358: case CPU_R5500: if (m4kc_tlbp_war()) uasm_i_nop(p); diff --git a/trunk/arch/mips/mm/uasm.c b/trunk/arch/mips/mm/uasm.c index 23afdebc8e5c..d2647a4e012b 100644 --- a/trunk/arch/mips/mm/uasm.c +++ b/trunk/arch/mips/mm/uasm.c @@ -405,6 +405,7 @@ I_u1u2u3(_mfc0) I_u1u2u3(_mtc0) I_u2u1u3(_ori) I_u3u1u2(_or) +I_u2s3u1(_pref) I_0(_rfe) I_u2s3u1(_sc) I_u2s3u1(_scd) @@ -426,25 +427,6 @@ I_u1(_syscall); I_u1u2s3(_bbit0); I_u1u2s3(_bbit1); -#ifdef CONFIG_CPU_CAVIUM_OCTEON -#include -void __uasminit uasm_i_pref(u32 **buf, unsigned int a, signed int b, - unsigned int c) -{ - if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) && a <= 24 && a != 5) - /* - * As per erratum Core-14449, replace prefetches 0-4, - * 6-24 with 'pref 28'. - */ - build_insn(buf, insn_pref, c, 28, b); - else - build_insn(buf, insn_pref, c, a, b); -} -UASM_EXPORT_SYMBOL(uasm_i_pref); -#else -I_u2s3u1(_pref) -#endif - /* Handle labels. */ void __uasminit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid) { diff --git a/trunk/arch/mips/pci/pci-octeon.c b/trunk/arch/mips/pci/pci-octeon.c index 2d74fc9ae3ba..d248b707eff3 100644 --- a/trunk/arch/mips/pci/pci-octeon.c +++ b/trunk/arch/mips/pci/pci-octeon.c @@ -11,7 +11,6 @@ #include #include #include -#include #include @@ -20,8 +19,6 @@ #include #include -#include - #define USE_OCTEON_INTERNAL_ARBITER /* @@ -35,8 +32,6 @@ /* Octeon't PCI controller uses did=3, subdid=3 for PCI memory. */ #define OCTEON_PCI_MEMSPACE_OFFSET (0x00011b0000000000ull) -u64 octeon_bar1_pci_phys; - /** * This is the bit decoding used for the Octeon PCI controller addresses */ @@ -175,8 +170,6 @@ int pcibios_plat_dev_init(struct pci_dev *dev) pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig); } - dev->dev.archdata.dma_ops = octeon_pci_dma_map_ops; - return 0; } @@ -625,10 +618,12 @@ static int __init octeon_pci_setup(void) * before the readl()'s below. We don't want BAR2 overlapping * with BAR0/BAR1 during these reads. */ - octeon_npi_write32(CVMX_NPI_PCI_CFG08, - (u32)(OCTEON_BAR2_PCI_ADDRESS & 0xffffffffull)); - octeon_npi_write32(CVMX_NPI_PCI_CFG09, - (u32)(OCTEON_BAR2_PCI_ADDRESS >> 32)); + octeon_npi_write32(CVMX_NPI_PCI_CFG08, 0); + octeon_npi_write32(CVMX_NPI_PCI_CFG09, 0x80); + + /* Disable the BAR1 movable mappings */ + for (index = 0; index < 32; index++) + octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index), 0); if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG) { /* Remap the Octeon BAR 0 to 0-2GB */ @@ -642,25 +637,6 @@ static int __init octeon_pci_setup(void) octeon_npi_write32(CVMX_NPI_PCI_CFG06, 2ul << 30); octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0); - /* BAR1 movable mappings set for identity mapping */ - octeon_bar1_pci_phys = 0x80000000ull; - for (index = 0; index < 32; index++) { - union cvmx_pci_bar1_indexx bar1_index; - - bar1_index.u32 = 0; - /* Address bits[35:22] sent to L2C */ - bar1_index.s.addr_idx = - (octeon_bar1_pci_phys >> 22) + index; - /* 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); - } - /* Devices go after BAR1 */ octeon_pci_mem_resource.start = OCTEON_PCI_MEMSPACE_OFFSET + (4ul << 30) - @@ -676,27 +652,6 @@ static int __init octeon_pci_setup(void) octeon_npi_write32(CVMX_NPI_PCI_CFG06, 0); octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0); - /* BAR1 movable regions contiguous to cover the swiotlb */ - octeon_bar1_pci_phys = - virt_to_phys(octeon_swiotlb) & ~((1ull << 22) - 1); - - for (index = 0; index < 32; index++) { - union cvmx_pci_bar1_indexx bar1_index; - - bar1_index.u32 = 0; - /* Address bits[35:22] sent to L2C */ - bar1_index.s.addr_idx = - (octeon_bar1_pci_phys >> 22) + index; - /* 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); - } - /* Devices go after BAR0 */ octeon_pci_mem_resource.start = OCTEON_PCI_MEMSPACE_OFFSET + (128ul << 20) + @@ -712,9 +667,6 @@ static int __init octeon_pci_setup(void) * was setup properly. */ cvmx_write_csr(CVMX_NPI_PCI_INT_SUM2, -1); - - octeon_pci_dma_init(); - return 0; } diff --git a/trunk/arch/mips/pci/pcie-octeon.c b/trunk/arch/mips/pci/pcie-octeon.c index 385f035b24e4..861361e0c9af 100644 --- a/trunk/arch/mips/pci/pcie-octeon.c +++ b/trunk/arch/mips/pci/pcie-octeon.c @@ -75,8 +75,6 @@ union cvmx_pcie_address { } mem; }; -#include - /** * Return the Core virtual base address for PCIe IO access. IOs are * read/written as an offset from this address. @@ -1393,9 +1391,6 @@ static int __init octeon_pcie_setup(void) cvmx_pcie_get_io_size(1) - 1; register_pci_controller(&octeon_pcie1_controller); } - - octeon_pci_dma_init(); - return 0; } diff --git a/trunk/arch/powerpc/include/asm/kgdb.h b/trunk/arch/powerpc/include/asm/kgdb.h index 9db24e77b9f4..edd217006d27 100644 --- a/trunk/arch/powerpc/include/asm/kgdb.h +++ b/trunk/arch/powerpc/include/asm/kgdb.h @@ -31,7 +31,6 @@ static inline void arch_kgdb_breakpoint(void) asm(".long 0x7d821008"); /* twge r2, r2 */ } #define CACHE_FLUSH_IS_SAFE 1 -#define DBG_MAX_REG_NUM 70 /* The number bytes of registers we have to save depends on a few * things. For 64bit we default to not including vector registers and diff --git a/trunk/arch/powerpc/kernel/kgdb.c b/trunk/arch/powerpc/kernel/kgdb.c index 7a9db64f3f04..7f61a3ac787c 100644 --- a/trunk/arch/powerpc/kernel/kgdb.c +++ b/trunk/arch/powerpc/kernel/kgdb.c @@ -194,6 +194,40 @@ static int kgdb_dabr_match(struct pt_regs *regs) ptr = (unsigned long *)ptr32; \ } while (0) + +void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) +{ + unsigned long *ptr = gdb_regs; + int reg; + + memset(gdb_regs, 0, NUMREGBYTES); + + for (reg = 0; reg < 32; reg++) + PACK64(ptr, regs->gpr[reg]); + +#ifdef CONFIG_FSL_BOOKE +#ifdef CONFIG_SPE + for (reg = 0; reg < 32; reg++) + PACK64(ptr, current->thread.evr[reg]); +#else + ptr += 32; +#endif +#else + /* fp registers not used by kernel, leave zero */ + ptr += 32 * 8 / sizeof(long); +#endif + + PACK64(ptr, regs->nip); + PACK64(ptr, regs->msr); + PACK32(ptr, regs->ccr); + PACK64(ptr, regs->link); + PACK64(ptr, regs->ctr); + PACK32(ptr, regs->xer); + + BUG_ON((unsigned long)ptr > + (unsigned long)(((void *)gdb_regs) + NUMREGBYTES)); +} + void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) { struct pt_regs *regs = (struct pt_regs *)(p->thread.ksp + @@ -237,140 +271,44 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) (unsigned long)(((void *)gdb_regs) + NUMREGBYTES)); } -#define GDB_SIZEOF_REG sizeof(unsigned long) -#define GDB_SIZEOF_REG_U32 sizeof(u32) +#define UNPACK64(dest, ptr) do { dest = *(ptr++); } while (0) -#ifdef CONFIG_FSL_BOOKE -#define GDB_SIZEOF_FLOAT_REG sizeof(unsigned long) -#else -#define GDB_SIZEOF_FLOAT_REG sizeof(u64) -#endif +#define UNPACK32(dest, ptr) do { \ + u32 *ptr32; \ + ptr32 = (u32 *)ptr; \ + dest = *(ptr32++); \ + ptr = (unsigned long *)ptr32; \ + } while (0) -struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = +void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) { - { "r0", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[0]) }, - { "r1", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[1]) }, - { "r2", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[2]) }, - { "r3", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[3]) }, - { "r4", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[4]) }, - { "r5", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[5]) }, - { "r6", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[6]) }, - { "r7", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[7]) }, - { "r8", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[8]) }, - { "r9", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[9]) }, - { "r10", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[10]) }, - { "r11", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[11]) }, - { "r12", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[12]) }, - { "r13", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[13]) }, - { "r14", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[14]) }, - { "r15", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[15]) }, - { "r16", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[16]) }, - { "r17", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[17]) }, - { "r18", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[18]) }, - { "r19", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[19]) }, - { "r20", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[20]) }, - { "r21", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[21]) }, - { "r22", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[22]) }, - { "r23", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[23]) }, - { "r24", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[24]) }, - { "r25", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[25]) }, - { "r26", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[26]) }, - { "r27", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[27]) }, - { "r28", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[28]) }, - { "r29", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[29]) }, - { "r30", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[30]) }, - { "r31", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[31]) }, - - { "f0", GDB_SIZEOF_FLOAT_REG, 0 }, - { "f1", GDB_SIZEOF_FLOAT_REG, 1 }, - { "f2", GDB_SIZEOF_FLOAT_REG, 2 }, - { "f3", GDB_SIZEOF_FLOAT_REG, 3 }, - { "f4", GDB_SIZEOF_FLOAT_REG, 4 }, - { "f5", GDB_SIZEOF_FLOAT_REG, 5 }, - { "f6", GDB_SIZEOF_FLOAT_REG, 6 }, - { "f7", GDB_SIZEOF_FLOAT_REG, 7 }, - { "f8", GDB_SIZEOF_FLOAT_REG, 8 }, - { "f9", GDB_SIZEOF_FLOAT_REG, 9 }, - { "f10", GDB_SIZEOF_FLOAT_REG, 10 }, - { "f11", GDB_SIZEOF_FLOAT_REG, 11 }, - { "f12", GDB_SIZEOF_FLOAT_REG, 12 }, - { "f13", GDB_SIZEOF_FLOAT_REG, 13 }, - { "f14", GDB_SIZEOF_FLOAT_REG, 14 }, - { "f15", GDB_SIZEOF_FLOAT_REG, 15 }, - { "f16", GDB_SIZEOF_FLOAT_REG, 16 }, - { "f17", GDB_SIZEOF_FLOAT_REG, 17 }, - { "f18", GDB_SIZEOF_FLOAT_REG, 18 }, - { "f19", GDB_SIZEOF_FLOAT_REG, 19 }, - { "f20", GDB_SIZEOF_FLOAT_REG, 20 }, - { "f21", GDB_SIZEOF_FLOAT_REG, 21 }, - { "f22", GDB_SIZEOF_FLOAT_REG, 22 }, - { "f23", GDB_SIZEOF_FLOAT_REG, 23 }, - { "f24", GDB_SIZEOF_FLOAT_REG, 24 }, - { "f25", GDB_SIZEOF_FLOAT_REG, 25 }, - { "f26", GDB_SIZEOF_FLOAT_REG, 26 }, - { "f27", GDB_SIZEOF_FLOAT_REG, 27 }, - { "f28", GDB_SIZEOF_FLOAT_REG, 28 }, - { "f29", GDB_SIZEOF_FLOAT_REG, 29 }, - { "f30", GDB_SIZEOF_FLOAT_REG, 30 }, - { "f31", GDB_SIZEOF_FLOAT_REG, 31 }, - - { "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, nip) }, - { "msr", GDB_SIZEOF_REG, offsetof(struct pt_regs, msr) }, - { "cr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ccr) }, - { "lr", GDB_SIZEOF_REG, offsetof(struct pt_regs, link) }, - { "ctr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ctr) }, - { "xer", GDB_SIZEOF_REG, offsetof(struct pt_regs, xer) }, -}; + unsigned long *ptr = gdb_regs; + int reg; -char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs) -{ - if (regno >= DBG_MAX_REG_NUM || regno < 0) - return NULL; - - if (regno < 32 || regno >= 64) - /* First 0 -> 31 gpr registers*/ - /* pc, msr, ls... registers 64 -> 69 */ - memcpy(mem, (void *)regs + dbg_reg_def[regno].offset, - dbg_reg_def[regno].size); - - if (regno >= 32 && regno < 64) { - /* FP registers 32 -> 63 */ -#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE) - if (current) - memcpy(mem, current->thread.evr[regno-32], - dbg_reg_def[regno].size); + for (reg = 0; reg < 32; reg++) + UNPACK64(regs->gpr[reg], ptr); + +#ifdef CONFIG_FSL_BOOKE +#ifdef CONFIG_SPE + for (reg = 0; reg < 32; reg++) + UNPACK64(current->thread.evr[reg], ptr); #else - /* fp registers not used by kernel, leave zero */ - memset(mem, 0, dbg_reg_def[regno].size); + ptr += 32; #endif - } - - return dbg_reg_def[regno].name; -} - -int dbg_set_reg(int regno, void *mem, struct pt_regs *regs) -{ - if (regno >= DBG_MAX_REG_NUM || regno < 0) - return -EINVAL; - - if (regno < 32 || regno >= 64) - /* First 0 -> 31 gpr registers*/ - /* pc, msr, ls... registers 64 -> 69 */ - memcpy((void *)regs + dbg_reg_def[regno].offset, mem, - dbg_reg_def[regno].size); - - if (regno >= 32 && regno < 64) { - /* FP registers 32 -> 63 */ -#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE) - memcpy(current->thread.evr[regno-32], mem, - dbg_reg_def[regno].size); #else - /* fp registers not used by kernel, leave zero */ - return 0; + /* fp registers not used by kernel, leave zero */ + ptr += 32 * 8 / sizeof(int); #endif - } - return 0; + UNPACK64(regs->nip, ptr); + UNPACK64(regs->msr, ptr); + UNPACK32(regs->ccr, ptr); + UNPACK64(regs->link, ptr); + UNPACK64(regs->ctr, ptr); + UNPACK32(regs->xer, ptr); + + BUG_ON((unsigned long)ptr > + (unsigned long)(((void *)gdb_regs) + NUMREGBYTES)); } void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) diff --git a/trunk/arch/powerpc/platforms/cell/spufs/inode.c b/trunk/arch/powerpc/platforms/cell/spufs/inode.c index 3532b92de983..5dec408d6703 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/inode.c @@ -798,17 +798,17 @@ spufs_fill_super(struct super_block *sb, void *data, int silent) return spufs_create_root(sb, data); } -static struct dentry * -spufs_mount(struct file_system_type *fstype, int flags, - const char *name, void *data) +static int +spufs_get_sb(struct file_system_type *fstype, int flags, + const char *name, void *data, struct vfsmount *mnt) { - return mount_single(fstype, flags, data, spufs_fill_super); + return get_sb_single(fstype, flags, data, spufs_fill_super, mnt); } static struct file_system_type spufs_type = { .owner = THIS_MODULE, .name = "spufs", - .mount = spufs_mount, + .get_sb = spufs_get_sb, .kill_sb = kill_litter_super, }; diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index e0b98e71ff47..fabb40bc4e19 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -80,7 +80,6 @@ config S390 select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACE_MCOUNT_TEST select HAVE_FTRACE_MCOUNT_RECORD - select HAVE_C_RECORDMCOUNT select HAVE_SYSCALL_TRACEPOINTS select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_GRAPH_TRACER @@ -145,7 +144,7 @@ source "kernel/time/Kconfig" config 64BIT bool "64 bit kernel" help - Select this option if you have an IBM z/Architecture machine + Select this option if you have a 64 bit IBM zSeries machine and want to use the 64 bit addressing mode. config 32BIT @@ -197,18 +196,9 @@ config HOTPLUG_CPU can be controlled through /sys/devices/system/cpu/cpu#. Say N if you want to disable CPU hotplug. -config SCHED_MC - def_bool y - prompt "Multi-core scheduler support" - depends on SMP - help - Multi-core scheduler support improves the CPU scheduler's decision - making when dealing with multi-core CPU chips at a cost of slightly - increased overhead in some places. - config SCHED_BOOK bool "Book scheduler support" - depends on SMP && SCHED_MC + depends on SMP help Book scheduler support improves the CPU scheduler's decision making when dealing with machines that have several books. @@ -218,7 +208,7 @@ config MATHEMU depends on MARCH_G5 help This option is required for IEEE compliant floating point arithmetic - on older ESA/390 machines. Say Y unless you know your machine doesn't + on older S/390 machines. Say Y unless you know your machine doesn't need this. config COMPAT @@ -247,8 +237,8 @@ config S390_EXEC_PROTECT space programs and it also selects the addressing mode option above. The kernel parameter noexec=on will enable this feature and also switch the addressing modes, default is disabled. Enabling this (via - kernel parameter) on machines earlier than IBM System z9 this will - reduce system performance. + kernel parameter) on machines earlier than IBM System z9-109 EC/BC + will reduce system performance. comment "Code generation options" @@ -257,46 +247,49 @@ choice default MARCH_G5 config MARCH_G5 - bool "System/390 model G5 and G6" + bool "S/390 model G5 and G6" depends on !64BIT help Select this to build a 31 bit kernel that works - on all ESA/390 and z/Architecture machines. + on all S/390 and zSeries machines. config MARCH_Z900 - bool "IBM zSeries model z800 and z900" + bool "IBM eServer zSeries model z800 and z900" help - Select this to enable optimizations for model z800/z900 (2064 and - 2066 series). This will enable some optimizations that are not - available on older ESA/390 (31 Bit) only CPUs. + Select this to optimize for zSeries machines. This + will enable some optimizations that are not available + on older 31 bit only CPUs. config MARCH_Z990 - bool "IBM zSeries model z890 and z990" + bool "IBM eServer zSeries model z890 and z990" help - Select this to enable optimizations for model z890/z990 (2084 and - 2086 series). The kernel will be slightly faster but will not work - on older machines. + Select this enable optimizations for model z890/z990. + This will be slightly faster but does not work on + older machines such as the z900. config MARCH_Z9_109 bool "IBM System z9" help - Select this to enable optimizations for IBM System z9 (2094 and - 2096 series). The kernel will be slightly faster but will not work - on older machines. + Select this to enable optimizations for IBM System z9-109, IBM + System z9 Enterprise Class (z9 EC), and IBM System z9 Business + Class (z9 BC). The kernel will be slightly faster but will not + work on older machines such as the z990, z890, z900, and z800. config MARCH_Z10 bool "IBM System z10" help - Select this to enable optimizations for IBM System z10 (2097 and - 2098 series). The kernel will be slightly faster but will not work - on older machines. + Select this to enable optimizations for IBM System z10. The + kernel will be slightly faster but will not work on older + machines such as the z990, z890, z900, z800, z9-109, z9-ec + and z9-bc. config MARCH_Z196 bool "IBM zEnterprise 196" help - Select this to enable optimizations for IBM zEnterprise 196 - (2817 series). The kernel will be slightly faster but will not work - on older machines. + Select this to enable optimizations for IBM zEnterprise 196. + The kernel will be slightly faster but will not work on older + machines such as the z990, z890, z900, z800, z9-109, z9-ec, + z9-bc, z10-ec and z10-bc. endchoice diff --git a/trunk/arch/s390/hypfs/hypfs_diag.c b/trunk/arch/s390/hypfs/hypfs_diag.c index cd4a81be9cf8..020e51c063d2 100644 --- a/trunk/arch/s390/hypfs/hypfs_diag.c +++ b/trunk/arch/s390/hypfs/hypfs_diag.c @@ -638,21 +638,18 @@ __init int hypfs_diag_init(void) pr_err("The hardware system does not support hypfs\n"); return -ENODATA; } + rc = diag224_get_name_table(); + if (rc) { + diag204_free_buffer(); + pr_err("The hardware system does not provide all " + "functions required by hypfs\n"); + } if (diag204_info_type == INFO_EXT) { rc = hypfs_dbfs_init(); if (rc) - return rc; - } - if (MACHINE_IS_LPAR) { - rc = diag224_get_name_table(); - if (rc) { - pr_err("The hardware system does not provide all " - "functions required by hypfs\n"); - debugfs_remove(dbfs_d204_file); - return rc; - } + diag204_free_buffer(); } - return 0; + return rc; } void hypfs_diag_exit(void) diff --git a/trunk/arch/s390/hypfs/inode.c b/trunk/arch/s390/hypfs/inode.c index 47cc446dab8f..74d98670be27 100644 --- a/trunk/arch/s390/hypfs/inode.c +++ b/trunk/arch/s390/hypfs/inode.c @@ -316,10 +316,10 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent) return 0; } -static struct dentry *hypfs_mount(struct file_system_type *fst, int flags, - const char *devname, void *data) +static int hypfs_get_super(struct file_system_type *fst, int flags, + const char *devname, void *data, struct vfsmount *mnt) { - return mount_single(fst, flags, data, hypfs_fill_super); + return get_sb_single(fst, flags, data, hypfs_fill_super, mnt); } static void hypfs_kill_super(struct super_block *sb) @@ -455,7 +455,7 @@ static const struct file_operations hypfs_file_ops = { static struct file_system_type hypfs_type = { .owner = THIS_MODULE, .name = "s390_hypfs", - .mount = hypfs_mount, + .get_sb = hypfs_get_super, .kill_sb = hypfs_kill_super }; diff --git a/trunk/arch/s390/include/asm/dasd.h b/trunk/arch/s390/include/asm/dasd.h index b604a9186f8e..218bce81ec70 100644 --- a/trunk/arch/s390/include/asm/dasd.h +++ b/trunk/arch/s390/include/asm/dasd.h @@ -217,25 +217,6 @@ typedef struct dasd_symmio_parms { int rssd_result_len; } __attribute__ ((packed)) dasd_symmio_parms_t; -/* - * Data returned by Sense Path Group ID (SNID) - */ -struct dasd_snid_data { - struct { - __u8 group:2; - __u8 reserve:2; - __u8 mode:1; - __u8 res:3; - } __attribute__ ((packed)) path_state; - __u8 pgid[11]; -} __attribute__ ((packed)); - -struct dasd_snid_ioctl_data { - struct dasd_snid_data data; - __u8 path_mask; -} __attribute__ ((packed)); - - /******************************************************************************** * SECTION: Definition of IOCTLs * @@ -280,10 +261,25 @@ struct dasd_snid_ioctl_data { /* Set Attributes (cache operations) */ #define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t) -/* Get Sense Path Group ID (SNID) data */ -#define BIODASDSNID _IOWR(DASD_IOCTL_LETTER, 1, struct dasd_snid_ioctl_data) - #define BIODASDSYMMIO _IOWR(DASD_IOCTL_LETTER, 240, dasd_symmio_parms_t) #endif /* DASD_H */ +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-indent-level: 4 + * c-brace-imaginary-offset: 0 + * c-brace-offset: -4 + * c-argdecl-indent: 4 + * c-label-offset: -4 + * c-continued-statement-offset: 4 + * c-continued-brace-offset: 0 + * indent-tabs-mode: nil + * tab-width: 8 + * End: + */ diff --git a/trunk/arch/s390/kernel/asm-offsets.c b/trunk/arch/s390/kernel/asm-offsets.c index 33982e7ce04d..f3c1b823c9a8 100644 --- a/trunk/arch/s390/kernel/asm-offsets.c +++ b/trunk/arch/s390/kernel/asm-offsets.c @@ -66,9 +66,9 @@ int main(void) DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base)); DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time)); /* constants used by the vdso */ - DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME); - DEFINE(__CLOCK_MONOTONIC, CLOCK_MONOTONIC); - DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC); + DEFINE(CLOCK_REALTIME, CLOCK_REALTIME); + DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC); + DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC); BLANK(); /* constants for SIGP */ DEFINE(__SIGP_STOP, sigp_stop); diff --git a/trunk/arch/s390/kernel/early.c b/trunk/arch/s390/kernel/early.c index 3b7e7dddc324..d149609e46e6 100644 --- a/trunk/arch/s390/kernel/early.c +++ b/trunk/arch/s390/kernel/early.c @@ -282,6 +282,8 @@ static noinline __init void setup_facility_list(void) static noinline __init void setup_hpage(void) { #ifndef CONFIG_DEBUG_PAGEALLOC + unsigned int facilities; + if (!test_facility(2) || !test_facility(8)) return; S390_lowcore.machine_flags |= MACHINE_FLAG_HPAGE; diff --git a/trunk/arch/s390/kernel/entry.S b/trunk/arch/s390/kernel/entry.S index 1ecc337fb679..5efce7202984 100644 --- a/trunk/arch/s390/kernel/entry.S +++ b/trunk/arch/s390/kernel/entry.S @@ -557,7 +557,6 @@ pgm_svcper: # per was called from kernel, must be kprobes # kernel_per: - REENABLE_IRQS mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check mvi SP_SVCNR+1(%r15),0xff la %r2,SP_PTREGS(%r15) # address of register-save area diff --git a/trunk/arch/s390/kernel/entry64.S b/trunk/arch/s390/kernel/entry64.S index 8f3e802174db..a2be23922f43 100644 --- a/trunk/arch/s390/kernel/entry64.S +++ b/trunk/arch/s390/kernel/entry64.S @@ -568,7 +568,6 @@ pgm_svcper: # per was called from kernel, must be kprobes # kernel_per: - REENABLE_IRQS xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number la %r2,SP_PTREGS(%r15) # address of register-save area brasl %r14,do_single_step diff --git a/trunk/arch/s390/kernel/kprobes.c b/trunk/arch/s390/kernel/kprobes.c index d60fc4398516..2a3d2bf6f083 100644 --- a/trunk/arch/s390/kernel/kprobes.c +++ b/trunk/arch/s390/kernel/kprobes.c @@ -316,8 +316,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) return 1; ss_probe: - if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO)) - local_irq_disable(); prepare_singlestep(p, regs); kcb->kprobe_status = KPROBE_HIT_SS; return 1; @@ -465,8 +463,6 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs) goto out; } reset_current_kprobe(); - if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO)) - local_irq_enable(); out: preempt_enable_no_resched(); @@ -506,11 +502,8 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) regs->psw.mask |= kcb->kprobe_saved_imask; if (kcb->kprobe_status == KPROBE_REENTER) restore_previous_kprobe(kcb); - else { + else reset_current_kprobe(); - if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO)) - local_irq_enable(); - } preempt_enable_no_resched(); break; case KPROBE_HIT_ACTIVE: diff --git a/trunk/arch/s390/kernel/setup.c b/trunk/arch/s390/kernel/setup.c index 6f6350826c81..e3ceb911dc75 100644 --- a/trunk/arch/s390/kernel/setup.c +++ b/trunk/arch/s390/kernel/setup.c @@ -761,9 +761,6 @@ static void __init setup_hwcaps(void) case 0x2098: strcpy(elf_platform, "z10"); break; - case 0x2817: - strcpy(elf_platform, "z196"); - break; } } diff --git a/trunk/arch/s390/kernel/sysinfo.c b/trunk/arch/s390/kernel/sysinfo.c index 5c9e439bf3f6..f04d93aa48ec 100644 --- a/trunk/arch/s390/kernel/sysinfo.c +++ b/trunk/arch/s390/kernel/sysinfo.c @@ -106,13 +106,11 @@ static int stsi_15_1_x(struct sysinfo_15_1_x *info, char *page, int len) for (i = 0; i < TOPOLOGY_NR_MAG; i++) len += sprintf(page + len, " %d", info->mag[i]); len += sprintf(page + len, "\n"); -#ifdef CONFIG_SCHED_MC store_topology(info); len += sprintf(page + len, "CPU Topology SW: "); for (i = 0; i < TOPOLOGY_NR_MAG; i++) len += sprintf(page + len, " %d", info->mag[i]); len += sprintf(page + len, "\n"); -#endif return len; } diff --git a/trunk/arch/s390/kernel/topology.c b/trunk/arch/s390/kernel/topology.c index 94b06c31fc8a..a9dee9048ee5 100644 --- a/trunk/arch/s390/kernel/topology.c +++ b/trunk/arch/s390/kernel/topology.c @@ -53,10 +53,8 @@ static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) cpumask_t mask; cpus_clear(mask); - if (!topology_enabled || !MACHINE_HAS_TOPOLOGY) { - cpumask_copy(&mask, cpumask_of(cpu)); - return mask; - } + if (!topology_enabled || !MACHINE_HAS_TOPOLOGY) + return cpu_possible_map; while (info) { if (cpu_isset(cpu, info->mask)) { mask = info->mask; diff --git a/trunk/arch/s390/kernel/vdso32/clock_getres.S b/trunk/arch/s390/kernel/vdso32/clock_getres.S index 36aaa25d05da..9532c4e6a9d2 100644 --- a/trunk/arch/s390/kernel/vdso32/clock_getres.S +++ b/trunk/arch/s390/kernel/vdso32/clock_getres.S @@ -19,9 +19,9 @@ .type __kernel_clock_getres,@function __kernel_clock_getres: .cfi_startproc - chi %r2,__CLOCK_REALTIME + chi %r2,CLOCK_REALTIME je 0f - chi %r2,__CLOCK_MONOTONIC + chi %r2,CLOCK_MONOTONIC jne 3f 0: ltr %r3,%r3 jz 2f /* res == NULL */ @@ -34,6 +34,6 @@ __kernel_clock_getres: 3: lhi %r1,__NR_clock_getres /* fallback to svc */ svc 0 br %r14 -4: .long __CLOCK_REALTIME_RES +4: .long CLOCK_REALTIME_RES .cfi_endproc .size __kernel_clock_getres,.-__kernel_clock_getres diff --git a/trunk/arch/s390/kernel/vdso32/clock_gettime.S b/trunk/arch/s390/kernel/vdso32/clock_gettime.S index b2224e0b974c..969643954273 100644 --- a/trunk/arch/s390/kernel/vdso32/clock_gettime.S +++ b/trunk/arch/s390/kernel/vdso32/clock_gettime.S @@ -21,9 +21,9 @@ __kernel_clock_gettime: .cfi_startproc basr %r5,0 0: al %r5,21f-0b(%r5) /* get &_vdso_data */ - chi %r2,__CLOCK_REALTIME + chi %r2,CLOCK_REALTIME je 10f - chi %r2,__CLOCK_MONOTONIC + chi %r2,CLOCK_MONOTONIC jne 19f /* CLOCK_MONOTONIC */ diff --git a/trunk/arch/s390/kernel/vdso64/clock_getres.S b/trunk/arch/s390/kernel/vdso64/clock_getres.S index 176e1f75f9aa..9ce8caafdb4e 100644 --- a/trunk/arch/s390/kernel/vdso64/clock_getres.S +++ b/trunk/arch/s390/kernel/vdso64/clock_getres.S @@ -19,9 +19,9 @@ .type __kernel_clock_getres,@function __kernel_clock_getres: .cfi_startproc - cghi %r2,__CLOCK_REALTIME + cghi %r2,CLOCK_REALTIME je 0f - cghi %r2,__CLOCK_MONOTONIC + cghi %r2,CLOCK_MONOTONIC je 0f cghi %r2,-2 /* CLOCK_THREAD_CPUTIME_ID for this thread */ jne 2f @@ -39,6 +39,6 @@ __kernel_clock_getres: 2: lghi %r1,__NR_clock_getres /* fallback to svc */ svc 0 br %r14 -3: .quad __CLOCK_REALTIME_RES +3: .quad CLOCK_REALTIME_RES .cfi_endproc .size __kernel_clock_getres,.-__kernel_clock_getres diff --git a/trunk/arch/s390/kernel/vdso64/clock_gettime.S b/trunk/arch/s390/kernel/vdso64/clock_gettime.S index d46c95ed5f19..f40467884a03 100644 --- a/trunk/arch/s390/kernel/vdso64/clock_gettime.S +++ b/trunk/arch/s390/kernel/vdso64/clock_gettime.S @@ -20,11 +20,11 @@ __kernel_clock_gettime: .cfi_startproc larl %r5,_vdso_data - cghi %r2,__CLOCK_REALTIME + cghi %r2,CLOCK_REALTIME je 4f cghi %r2,-2 /* CLOCK_THREAD_CPUTIME_ID for this thread */ je 9f - cghi %r2,__CLOCK_MONOTONIC + cghi %r2,CLOCK_MONOTONIC jne 12f /* CLOCK_MONOTONIC */ diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index 45d9c87d083a..a9aaed3c3d97 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -22,6 +22,8 @@ config SPARC select RTC_CLASS select RTC_DRV_M48T59 select HAVE_IRQ_WORK + select HAVE_PERF_EVENTS + select PERF_USE_VMALLOC select HAVE_DMA_ATTRS select HAVE_DMA_API_DEBUG select HAVE_ARCH_JUMP_LABEL @@ -48,6 +50,7 @@ config SPARC64 select RTC_DRV_BQ4802 select RTC_DRV_SUN4V select RTC_DRV_STARFIRE + select HAVE_IRQ_WORK select HAVE_PERF_EVENTS select PERF_USE_VMALLOC diff --git a/trunk/arch/sparc/include/asm/jump_label.h b/trunk/arch/sparc/include/asm/jump_label.h index 65c0d3029796..62e66d7b2fb6 100644 --- a/trunk/arch/sparc/include/asm/jump_label.h +++ b/trunk/arch/sparc/include/asm/jump_label.h @@ -4,6 +4,7 @@ #ifdef __KERNEL__ #include +#include #define JUMP_LABEL_NOP_SIZE 4 diff --git a/trunk/arch/sparc/kernel/irq_32.c b/trunk/arch/sparc/kernel/irq_32.c index 5ad6e5c5dbb3..0116d8d10def 100644 --- a/trunk/arch/sparc/kernel/irq_32.c +++ b/trunk/arch/sparc/kernel/irq_32.c @@ -365,7 +365,7 @@ static int request_fast_irq(unsigned int irq, unsigned long flags; unsigned int cpu_irq; int ret; -#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON +#ifdef CONFIG_SMP struct tt_entry *trap_table; extern struct tt_entry trapbase_cpu1, trapbase_cpu2, trapbase_cpu3; #endif @@ -425,7 +425,7 @@ static int request_fast_irq(unsigned int irq, table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP; INSTANTIATE(sparc_ttable) -#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON +#ifdef CONFIG_SMP trap_table = &trapbase_cpu1; INSTANTIATE(trap_table) trap_table = &trapbase_cpu2; INSTANTIATE(trap_table) trap_table = &trapbase_cpu3; INSTANTIATE(trap_table) diff --git a/trunk/arch/sparc/kernel/leon_smp.c b/trunk/arch/sparc/kernel/leon_smp.c index 7524689b03d2..e1656fc41ccb 100644 --- a/trunk/arch/sparc/kernel/leon_smp.c +++ b/trunk/arch/sparc/kernel/leon_smp.c @@ -56,8 +56,8 @@ void __init leon_configure_cache_smp(void); static inline unsigned long do_swap(volatile unsigned long *ptr, unsigned long val) { - __asm__ __volatile__("swapa [%2] %3, %0\n\t" : "=&r"(val) - : "0"(val), "r"(ptr), "i"(ASI_LEON_DCACHE_MISS) + __asm__ __volatile__("swapa [%1] %2, %0\n\t" : "=&r"(val) + : "r"(ptr), "i"(ASI_LEON_DCACHE_MISS) : "memory"); return val; } diff --git a/trunk/arch/sparc/kernel/rtrap_32.S b/trunk/arch/sparc/kernel/rtrap_32.S index 5f5f74c2c2ca..4da2e1f66290 100644 --- a/trunk/arch/sparc/kernel/rtrap_32.S +++ b/trunk/arch/sparc/kernel/rtrap_32.S @@ -78,9 +78,9 @@ signal_p: call do_notify_resume add %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr - b signal_p - ld [%curptr + TI_FLAGS], %g2 - + /* Fall through. */ + ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr + clr %l6 ret_trap_continue: sethi %hi(PSR_SYSCALL), %g1 andn %t_psr, %g1, %t_psr diff --git a/trunk/arch/sparc/kernel/rtrap_64.S b/trunk/arch/sparc/kernel/rtrap_64.S index 77f1b95e0806..090b9e9ad5e3 100644 --- a/trunk/arch/sparc/kernel/rtrap_64.S +++ b/trunk/arch/sparc/kernel/rtrap_64.S @@ -34,9 +34,37 @@ __handle_preemption: __handle_user_windows: call fault_in_user_windows wrpr %g0, RTRAP_PSTATE, %pstate - ba,pt %xcc, __handle_preemption_continue - wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate + wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate + /* Redo sched+sig checks */ + ldx [%g6 + TI_FLAGS], %l0 + andcc %l0, _TIF_NEED_RESCHED, %g0 + + be,pt %xcc, 1f + nop + call schedule + wrpr %g0, RTRAP_PSTATE, %pstate + wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate + ldx [%g6 + TI_FLAGS], %l0 + +1: andcc %l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0 + be,pt %xcc, __handle_user_windows_continue + nop + mov %l5, %o1 + add %sp, PTREGS_OFF, %o0 + mov %l0, %o2 + + call do_notify_resume + wrpr %g0, RTRAP_PSTATE, %pstate + wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate + /* Signal delivery can modify pt_regs tstate, so we must + * reload it. + */ + ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 + sethi %hi(0xf << 20), %l4 + and %l1, %l4, %l4 + ba,pt %xcc, __handle_user_windows_continue + andn %l1, %l4, %l1 __handle_userfpu: rd %fprs, %l5 andcc %l5, FPRS_FEF, %g0 @@ -59,7 +87,7 @@ __handle_signal: ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 sethi %hi(0xf << 20), %l4 and %l1, %l4, %l4 - ba,pt %xcc, __handle_preemption_continue + ba,pt %xcc, __handle_signal_continue andn %l1, %l4, %l1 /* When returning from a NMI (%pil==15) interrupt we want to @@ -149,9 +177,11 @@ __handle_preemption_continue: bne,pn %xcc, __handle_preemption andcc %l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0 bne,pn %xcc, __handle_signal +__handle_signal_continue: ldub [%g6 + TI_WSAVED], %o2 brnz,pn %o2, __handle_user_windows nop +__handle_user_windows_continue: sethi %hi(TSTATE_PEF), %o0 andcc %l1, %o0, %g0 diff --git a/trunk/arch/sparc/mm/fault_32.c b/trunk/arch/sparc/mm/fault_32.c index 5b836f5aea90..bd8601601afa 100644 --- a/trunk/arch/sparc/mm/fault_32.c +++ b/trunk/arch/sparc/mm/fault_32.c @@ -539,12 +539,6 @@ static void force_user_fault(unsigned long address, int write) __do_fault_siginfo(BUS_ADRERR, SIGBUS, tsk->thread.kregs, address); } -static void check_stack_aligned(unsigned long sp) -{ - if (sp & 0x7UL) - force_sig(SIGILL, current); -} - void window_overflow_fault(void) { unsigned long sp; @@ -553,8 +547,6 @@ void window_overflow_fault(void) if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) force_user_fault(sp + 0x38, 1); force_user_fault(sp, 1); - - check_stack_aligned(sp); } void window_underflow_fault(unsigned long sp) @@ -562,8 +554,6 @@ void window_underflow_fault(unsigned long sp) if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) force_user_fault(sp + 0x38, 0); force_user_fault(sp, 0); - - check_stack_aligned(sp); } void window_ret_fault(struct pt_regs *regs) @@ -574,6 +564,4 @@ void window_ret_fault(struct pt_regs *regs) if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) force_user_fault(sp + 0x38, 0); force_user_fault(sp, 0); - - check_stack_aligned(sp); } diff --git a/trunk/arch/x86/kernel/kgdb.c b/trunk/arch/x86/kernel/kgdb.c index ec592caac4b4..d81cfebb848f 100644 --- a/trunk/arch/x86/kernel/kgdb.c +++ b/trunk/arch/x86/kernel/kgdb.c @@ -387,7 +387,7 @@ kgdb_set_hw_break(unsigned long addr, int len, enum kgdb_bptype bptype) * disable hardware debugging while it is processing gdb packets or * handling exception. */ -static void kgdb_disable_hw_debug(struct pt_regs *regs) +void kgdb_disable_hw_debug(struct pt_regs *regs) { int i; int cpu = raw_smp_processor_id(); @@ -724,7 +724,6 @@ struct kgdb_arch arch_kgdb_ops = { .flags = KGDB_HW_BREAKPOINT, .set_hw_breakpoint = kgdb_set_hw_break, .remove_hw_breakpoint = kgdb_remove_hw_break, - .disable_hw_break = kgdb_disable_hw_debug, .remove_all_hw_break = kgdb_remove_all_hw_break, .correct_hw_break = kgdb_correct_hw_break, }; diff --git a/trunk/drivers/ata/pata_octeon_cf.c b/trunk/drivers/ata/pata_octeon_cf.c index 74b829817891..06ddd91ffeda 100644 --- a/trunk/drivers/ata/pata_octeon_cf.c +++ b/trunk/drivers/ata/pata_octeon_cf.c @@ -60,7 +60,7 @@ static unsigned int ns_to_tim_reg(unsigned int tim_mult, unsigned int nsecs) * Compute # of eclock periods to get desired duration in * nanoseconds. */ - val = DIV_ROUND_UP(nsecs * (octeon_get_io_clock_rate() / 1000000), + val = DIV_ROUND_UP(nsecs * (octeon_get_clock_rate() / 1000000), 1000 * tim_mult); return val; diff --git a/trunk/drivers/base/devtmpfs.c b/trunk/drivers/base/devtmpfs.c index 82bbb5967aa9..af0600143d1c 100644 --- a/trunk/drivers/base/devtmpfs.c +++ b/trunk/drivers/base/devtmpfs.c @@ -29,33 +29,33 @@ static struct vfsmount *dev_mnt; #if defined CONFIG_DEVTMPFS_MOUNT -static int mount_dev = 1; +static int dev_mount = 1; #else -static int mount_dev; +static int dev_mount; #endif static DEFINE_MUTEX(dirlock); static int __init mount_param(char *str) { - mount_dev = simple_strtoul(str, NULL, 0); + dev_mount = simple_strtoul(str, NULL, 0); return 1; } __setup("devtmpfs.mount=", mount_param); -static struct dentry *dev_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *data) +static int dev_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, struct vfsmount *mnt) { #ifdef CONFIG_TMPFS - return mount_single(fs_type, flags, data, shmem_fill_super); + return get_sb_single(fs_type, flags, data, shmem_fill_super, mnt); #else - return mount_single(fs_type, flags, data, ramfs_fill_super); + return get_sb_single(fs_type, flags, data, ramfs_fill_super, mnt); #endif } static struct file_system_type dev_fs_type = { .name = "devtmpfs", - .mount = dev_mount, + .get_sb = dev_get_sb, .kill_sb = kill_litter_super, }; @@ -351,7 +351,7 @@ int devtmpfs_mount(const char *mntdir) { int err; - if (!mount_dev) + if (!dev_mount) return 0; if (!dev_mnt) diff --git a/trunk/drivers/char/agp/parisc-agp.c b/trunk/drivers/char/agp/parisc-agp.c index 94821ab01c6d..17e380f5f818 100644 --- a/trunk/drivers/char/agp/parisc-agp.c +++ b/trunk/drivers/char/agp/parisc-agp.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/dma/Kconfig b/trunk/drivers/dma/Kconfig index 6ee23592700a..79d1542f31c0 100644 --- a/trunk/drivers/dma/Kconfig +++ b/trunk/drivers/dma/Kconfig @@ -200,11 +200,11 @@ config PL330_DMA platform_data for a dma-pl330 device. config PCH_DMA - tristate "Topcliff (Intel EG20T) PCH DMA support" + tristate "Topcliff PCH DMA support" depends on PCI && X86 select DMA_ENGINE help - Enable support for the Topcliff (Intel EG20T) PCH DMA engine. + Enable support for the Topcliff PCH DMA engine. config IMX_SDMA tristate "i.MX SDMA support" diff --git a/trunk/drivers/ide/hpt366.c b/trunk/drivers/ide/hpt366.c index 58c51cddc100..97d98fbf5849 100644 --- a/trunk/drivers/ide/hpt366.c +++ b/trunk/drivers/ide/hpt366.c @@ -838,7 +838,7 @@ static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode) static void hpt3xxn_rw_disk(ide_drive_t *drive, struct request *rq) { - hpt3xxn_set_clock(drive->hwif, rq_data_dir(rq) ? 0x21 : 0x23); + hpt3xxn_set_clock(drive->hwif, rq_data_dir(rq) ? 0x23 : 0x21); } /** @@ -1173,9 +1173,8 @@ static u8 hpt3xx_cable_detect(ide_hwif_t *hwif) u16 mcr; pci_read_config_word(dev, mcr_addr, &mcr); - pci_write_config_word(dev, mcr_addr, mcr | 0x8000); - /* Debounce, then read cable ID register */ - udelay(10); + pci_write_config_word(dev, mcr_addr, (mcr | 0x8000)); + /* now read cable id register */ pci_read_config_byte(dev, 0x5a, &scr1); pci_write_config_word(dev, mcr_addr, mcr); } else if (chip_type >= HPT370) { @@ -1186,11 +1185,10 @@ static u8 hpt3xx_cable_detect(ide_hwif_t *hwif) u8 scr2 = 0; pci_read_config_byte(dev, 0x5b, &scr2); - pci_write_config_byte(dev, 0x5b, scr2 & ~1); - /* Debounce, then read cable ID register */ - udelay(10); + pci_write_config_byte(dev, 0x5b, (scr2 & ~1)); + /* now read cable id register */ pci_read_config_byte(dev, 0x5a, &scr1); - pci_write_config_byte(dev, 0x5b, scr2); + pci_write_config_byte(dev, 0x5b, scr2); } else pci_read_config_byte(dev, 0x5a, &scr1); diff --git a/trunk/drivers/ide/ide-dma.c b/trunk/drivers/ide/ide-dma.c index d4136908f916..06b14bc9a1d4 100644 --- a/trunk/drivers/ide/ide-dma.c +++ b/trunk/drivers/ide/ide-dma.c @@ -449,6 +449,7 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) ide_hwif_t *hwif = drive->hwif; const struct ide_dma_ops *dma_ops = hwif->dma_ops; struct ide_cmd *cmd = &hwif->cmd; + struct request *rq; ide_startstop_t ret = ide_stopped; /* @@ -486,10 +487,14 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) ide_dma_off_quietly(drive); /* - * make sure request is sane + * un-busy drive etc and make sure request is sane */ - if (hwif->rq) - hwif->rq->errors = 0; + rq = hwif->rq; + if (rq) { + hwif->rq = NULL; + rq->errors = 0; + ide_requeue_and_plug(drive, rq); + } return ret; } diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_fs.c b/trunk/drivers/infiniband/hw/ipath/ipath_fs.c index 8c8afc716b98..12d5bf76302c 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_fs.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_fs.c @@ -362,13 +362,13 @@ static int ipathfs_fill_super(struct super_block *sb, void *data, return ret; } -static struct dentry *ipathfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int ipathfs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, struct vfsmount *mnt) { - struct dentry *ret; - ret = mount_single(fs_type, flags, data, ipathfs_fill_super); - if (!IS_ERR(ret)) - ipath_super = ret->d_sb; + int ret = get_sb_single(fs_type, flags, data, + ipathfs_fill_super, mnt); + if (ret >= 0) + ipath_super = mnt->mnt_sb; return ret; } @@ -411,7 +411,7 @@ int ipathfs_remove_device(struct ipath_devdata *dd) static struct file_system_type ipathfs_fs_type = { .owner = THIS_MODULE, .name = "ipathfs", - .mount = ipathfs_mount, + .get_sb = ipathfs_get_sb, .kill_sb = ipathfs_kill_super, }; diff --git a/trunk/drivers/infiniband/hw/qib/qib_fs.c b/trunk/drivers/infiniband/hw/qib/qib_fs.c index f99bddc01716..7e433d75c775 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_fs.c +++ b/trunk/drivers/infiniband/hw/qib/qib_fs.c @@ -555,13 +555,13 @@ static int qibfs_fill_super(struct super_block *sb, void *data, int silent) return ret; } -static struct dentry *qibfs_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *data) +static int qibfs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, struct vfsmount *mnt) { - struct dentry *ret; - ret = mount_single(fs_type, flags, data, qibfs_fill_super); - if (!IS_ERR(ret)) - qib_super = ret->d_sb; + int ret = get_sb_single(fs_type, flags, data, + qibfs_fill_super, mnt); + if (ret >= 0) + qib_super = mnt->mnt_sb; return ret; } @@ -603,7 +603,7 @@ int qibfs_remove(struct qib_devdata *dd) static struct file_system_type qibfs_fs_type = { .owner = THIS_MODULE, .name = "ipathfs", - .mount = qibfs_mount, + .get_sb = qibfs_get_sb, .kill_sb = qibfs_kill_super, }; diff --git a/trunk/drivers/isdn/capi/capifs.c b/trunk/drivers/isdn/capi/capifs.c index b4faed7fe0d3..2b83850997c3 100644 --- a/trunk/drivers/isdn/capi/capifs.c +++ b/trunk/drivers/isdn/capi/capifs.c @@ -125,16 +125,16 @@ capifs_fill_super(struct super_block *s, void *data, int silent) return -ENOMEM; } -static struct dentry *capifs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int capifs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_single(fs_type, flags, data, capifs_fill_super); + return get_sb_single(fs_type, flags, data, capifs_fill_super, mnt); } static struct file_system_type capifs_fs_type = { .owner = THIS_MODULE, .name = "capifs", - .mount = capifs_mount, + .get_sb = capifs_get_sb, .kill_sb = kill_anon_super, }; diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c index 5a1ffe3527aa..e4fb58db5454 100644 --- a/trunk/drivers/md/bitmap.c +++ b/trunk/drivers/md/bitmap.c @@ -212,7 +212,7 @@ static struct page *read_sb_page(mddev_t *mddev, loff_t offset, target = rdev->sb_start + offset + index * (PAGE_SIZE/512); - if (sync_page_io(rdev, target, + if (sync_page_io(rdev->bdev, target, roundup(size, bdev_logical_block_size(rdev->bdev)), page, READ)) { page->index = index; @@ -343,7 +343,7 @@ static void write_page(struct bitmap *bitmap, struct page *page, int wait) atomic_inc(&bitmap->pending_writes); set_buffer_locked(bh); set_buffer_mapped(bh); - submit_bh(WRITE | REQ_UNPLUG | REQ_SYNC, bh); + submit_bh(WRITE, bh); bh = bh->b_this_page; } @@ -1101,7 +1101,7 @@ static void bitmap_count_page(struct bitmap *bitmap, sector_t offset, int inc) bitmap_checkfree(bitmap, page); } static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, - sector_t offset, sector_t *blocks, + sector_t offset, int *blocks, int create); /* @@ -1115,7 +1115,7 @@ void bitmap_daemon_work(mddev_t *mddev) unsigned long j; unsigned long flags; struct page *page = NULL, *lastpage = NULL; - sector_t blocks; + int blocks; void *paddr; struct dm_dirty_log *log = mddev->bitmap_info.log; @@ -1258,7 +1258,7 @@ void bitmap_daemon_work(mddev_t *mddev) } static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, - sector_t offset, sector_t *blocks, + sector_t offset, int *blocks, int create) __releases(bitmap->lock) __acquires(bitmap->lock) @@ -1316,7 +1316,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect } while (sectors) { - sector_t blocks; + int blocks; bitmap_counter_t *bmc; spin_lock_irq(&bitmap->lock); @@ -1381,7 +1381,7 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto success = 0; while (sectors) { - sector_t blocks; + int blocks; unsigned long flags; bitmap_counter_t *bmc; @@ -1423,7 +1423,7 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto } EXPORT_SYMBOL(bitmap_endwrite); -static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, +static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int degraded) { bitmap_counter_t *bmc; @@ -1452,7 +1452,7 @@ static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t return rv; } -int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, +int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int degraded) { /* bitmap_start_sync must always report on multiples of whole @@ -1463,7 +1463,7 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, * Return the 'or' of the result. */ int rv = 0; - sector_t blocks1; + int blocks1; *blocks = 0; while (*blocks < (PAGE_SIZE>>9)) { @@ -1476,7 +1476,7 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, } EXPORT_SYMBOL(bitmap_start_sync); -void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted) +void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted) { bitmap_counter_t *bmc; unsigned long flags; @@ -1515,7 +1515,7 @@ void bitmap_close_sync(struct bitmap *bitmap) * RESYNC bit wherever it is still on */ sector_t sector = 0; - sector_t blocks; + int blocks; if (!bitmap) return; while (sector < bitmap->mddev->resync_max_sectors) { @@ -1528,7 +1528,7 @@ EXPORT_SYMBOL(bitmap_close_sync); void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector) { sector_t s = 0; - sector_t blocks; + int blocks; if (!bitmap) return; @@ -1562,7 +1562,7 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int n * be 0 at this point */ - sector_t secs; + int secs; bitmap_counter_t *bmc; spin_lock_irq(&bitmap->lock); bmc = bitmap_get_counter(bitmap, offset, &secs, 1); @@ -1790,7 +1790,7 @@ int bitmap_load(mddev_t *mddev) * All chunks should be clean, but some might need_sync. */ while (sector < mddev->resync_max_sectors) { - sector_t blocks; + int blocks; bitmap_start_sync(bitmap, sector, &blocks, 0); sector += blocks; } diff --git a/trunk/drivers/md/bitmap.h b/trunk/drivers/md/bitmap.h index 931a7a7c3796..e872a7bad6b8 100644 --- a/trunk/drivers/md/bitmap.h +++ b/trunk/drivers/md/bitmap.h @@ -271,8 +271,8 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int behind); void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int success, int behind); -int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int degraded); -void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted); +int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int degraded); +void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted); void bitmap_close_sync(struct bitmap *bitmap); void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector); diff --git a/trunk/drivers/md/faulty.c b/trunk/drivers/md/faulty.c index 339fdc670751..1a8987884614 100644 --- a/trunk/drivers/md/faulty.c +++ b/trunk/drivers/md/faulty.c @@ -210,7 +210,7 @@ static int make_request(mddev_t *mddev, struct bio *bio) } } if (failit) { - struct bio *b = bio_clone_mddev(bio, GFP_NOIO, mddev); + struct bio *b = bio_clone(bio, GFP_NOIO); b->bi_bdev = conf->rdev->bdev; b->bi_private = bio; b->bi_end_io = faulty_fail; diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 4e957f3140a8..225815197a3d 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -57,6 +57,8 @@ #define DEBUG 0 #define dprintk(x...) ((void)(DEBUG && printk(x))) +static DEFINE_MUTEX(md_mutex); + #ifndef MODULE static void autostart_arrays(int part); #endif @@ -67,8 +69,6 @@ static DEFINE_SPINLOCK(pers_lock); static void md_print_devices(void); static DECLARE_WAIT_QUEUE_HEAD(resync_wait); -static struct workqueue_struct *md_wq; -static struct workqueue_struct *md_misc_wq; #define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); } @@ -149,72 +149,6 @@ static const struct block_device_operations md_fops; static int start_readonly; -/* bio_clone_mddev - * like bio_clone, but with a local bio set - */ - -static void mddev_bio_destructor(struct bio *bio) -{ - mddev_t *mddev, **mddevp; - - mddevp = (void*)bio; - mddev = mddevp[-1]; - - bio_free(bio, mddev->bio_set); -} - -struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs, - mddev_t *mddev) -{ - struct bio *b; - mddev_t **mddevp; - - if (!mddev || !mddev->bio_set) - return bio_alloc(gfp_mask, nr_iovecs); - - b = bio_alloc_bioset(gfp_mask, nr_iovecs, - mddev->bio_set); - if (!b) - return NULL; - mddevp = (void*)b; - mddevp[-1] = mddev; - b->bi_destructor = mddev_bio_destructor; - return b; -} -EXPORT_SYMBOL_GPL(bio_alloc_mddev); - -struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask, - mddev_t *mddev) -{ - struct bio *b; - mddev_t **mddevp; - - if (!mddev || !mddev->bio_set) - return bio_clone(bio, gfp_mask); - - b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, - mddev->bio_set); - if (!b) - return NULL; - mddevp = (void*)b; - mddevp[-1] = mddev; - b->bi_destructor = mddev_bio_destructor; - __bio_clone(b, bio); - if (bio_integrity(bio)) { - int ret; - - ret = bio_integrity_clone(b, bio, gfp_mask, mddev->bio_set); - - if (ret < 0) { - bio_put(b); - return NULL; - } - } - - return b; -} -EXPORT_SYMBOL_GPL(bio_clone_mddev); - /* * We have a system wide 'event count' that is incremented * on any 'interesting' event, and readers of /proc/mdstat @@ -366,7 +300,7 @@ static void md_end_flush(struct bio *bio, int err) if (atomic_dec_and_test(&mddev->flush_pending)) { /* The pre-request flush has finished */ - queue_work(md_wq, &mddev->flush_work); + schedule_work(&mddev->flush_work); } bio_put(bio); } @@ -387,7 +321,7 @@ static void submit_flushes(mddev_t *mddev) atomic_inc(&rdev->nr_pending); atomic_inc(&rdev->nr_pending); rcu_read_unlock(); - bi = bio_alloc_mddev(GFP_KERNEL, 0, mddev); + bi = bio_alloc(GFP_KERNEL, 0); bi->bi_end_io = md_end_flush; bi->bi_private = rdev; bi->bi_bdev = rdev->bdev; @@ -435,7 +369,7 @@ void md_flush_request(mddev_t *mddev, struct bio *bio) submit_flushes(mddev); if (atomic_dec_and_test(&mddev->flush_pending)) - queue_work(md_wq, &mddev->flush_work); + schedule_work(&mddev->flush_work); } EXPORT_SYMBOL(md_flush_request); @@ -494,8 +428,6 @@ static void mddev_delayed_delete(struct work_struct *ws); static void mddev_put(mddev_t *mddev) { - struct bio_set *bs = NULL; - if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock)) return; if (!mddev->raid_disks && list_empty(&mddev->disks) && @@ -503,22 +435,19 @@ static void mddev_put(mddev_t *mddev) /* Array is not configured at all, and not held active, * so destroy it */ list_del(&mddev->all_mddevs); - bs = mddev->bio_set; - mddev->bio_set = NULL; if (mddev->gendisk) { - /* We did a probe so need to clean up. Call - * queue_work inside the spinlock so that - * flush_workqueue() after mddev_find will - * succeed in waiting for the work to be done. + /* we did a probe so need to clean up. + * Call schedule_work inside the spinlock + * so that flush_scheduled_work() after + * mddev_find will succeed in waiting for the + * work to be done. */ INIT_WORK(&mddev->del_work, mddev_delayed_delete); - queue_work(md_misc_wq, &mddev->del_work); + schedule_work(&mddev->del_work); } else kfree(mddev); } spin_unlock(&all_mddevs_lock); - if (bs) - bioset_free(bs); } void mddev_init(mddev_t *mddev) @@ -762,7 +691,7 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, * if zero is reached. * If an error occurred, call md_error */ - struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, mddev); + struct bio *bio = bio_alloc(GFP_NOIO, 1); bio->bi_bdev = rdev->bdev; bio->bi_sector = sector; @@ -793,16 +722,16 @@ static void bi_complete(struct bio *bio, int error) complete((struct completion*)bio->bi_private); } -int sync_page_io(mdk_rdev_t *rdev, sector_t sector, int size, - struct page *page, int rw) +int sync_page_io(struct block_device *bdev, sector_t sector, int size, + struct page *page, int rw) { - struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, rdev->mddev); + struct bio *bio = bio_alloc(GFP_NOIO, 1); struct completion event; int ret; rw |= REQ_SYNC | REQ_UNPLUG; - bio->bi_bdev = rdev->bdev; + bio->bi_bdev = bdev; bio->bi_sector = sector; bio_add_page(bio, page, size, 0); init_completion(&event); @@ -828,7 +757,7 @@ static int read_disk_sb(mdk_rdev_t * rdev, int size) return 0; - if (!sync_page_io(rdev, rdev->sb_start, size, rdev->sb_page, READ)) + if (!sync_page_io(rdev->bdev, rdev->sb_start, size, rdev->sb_page, READ)) goto fail; rdev->sb_loaded = 1; return 0; @@ -1921,7 +1850,7 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev) synchronize_rcu(); INIT_WORK(&rdev->del_work, md_delayed_delete); kobject_get(&rdev->kobj); - queue_work(md_misc_wq, &rdev->del_work); + schedule_work(&rdev->del_work); } /* @@ -2179,8 +2108,6 @@ static void md_update_sb(mddev_t * mddev, int force_change) if (!mddev->persistent) { clear_bit(MD_CHANGE_CLEAN, &mddev->flags); clear_bit(MD_CHANGE_DEVS, &mddev->flags); - if (!mddev->external) - clear_bit(MD_CHANGE_PENDING, &mddev->flags); wake_up(&mddev->sb_wait); return; } @@ -4265,10 +4192,10 @@ static int md_alloc(dev_t dev, char *name) shift = partitioned ? MdpMinorShift : 0; unit = MINOR(mddev->unit) >> shift; - /* wait for any previous instance of this device to be - * completely removed (mddev_delayed_delete). + /* wait for any previous instance if this device + * to be completed removed (mddev_delayed_delete). */ - flush_workqueue(md_misc_wq); + flush_scheduled_work(); mutex_lock(&disks_mutex); error = -EEXIST; @@ -4451,9 +4378,6 @@ int md_run(mddev_t *mddev) sysfs_notify_dirent_safe(rdev->sysfs_state); } - if (mddev->bio_set == NULL) - mddev->bio_set = bioset_create(BIO_POOL_SIZE, sizeof(mddev)); - spin_lock(&pers_lock); pers = find_pers(mddev->level, mddev->clevel); if (!pers || !try_module_get(pers->owner)) { @@ -5961,14 +5885,16 @@ static int md_open(struct block_device *bdev, fmode_t mode) mddev_t *mddev = mddev_find(bdev->bd_dev); int err; + mutex_lock(&md_mutex); if (mddev->gendisk != bdev->bd_disk) { /* we are racing with mddev_put which is discarding this * bd_disk. */ mddev_put(mddev); /* Wait until bdev->bd_disk is definitely gone */ - flush_workqueue(md_misc_wq); + flush_scheduled_work(); /* Then retry the open from the top */ + mutex_unlock(&md_mutex); return -ERESTARTSYS; } BUG_ON(mddev != bdev->bd_disk->private_data); @@ -5982,6 +5908,7 @@ static int md_open(struct block_device *bdev, fmode_t mode) check_disk_size_change(mddev->gendisk, bdev); out: + mutex_unlock(&md_mutex); return err; } @@ -5990,8 +5917,10 @@ static int md_release(struct gendisk *disk, fmode_t mode) mddev_t *mddev = disk->private_data; BUG_ON(!mddev); + mutex_lock(&md_mutex); atomic_dec(&mddev->openers); mddev_put(mddev); + mutex_unlock(&md_mutex); return 0; } @@ -6123,7 +6052,7 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev) set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); md_wakeup_thread(mddev->thread); if (mddev->event_work.func) - queue_work(md_misc_wq, &mddev->event_work); + schedule_work(&mddev->event_work); md_new_event_inintr(mddev); } @@ -7283,23 +7212,12 @@ static void md_geninit(void) static int __init md_init(void) { - int ret = -ENOMEM; - - md_wq = alloc_workqueue("md", WQ_RESCUER, 0); - if (!md_wq) - goto err_wq; - - md_misc_wq = alloc_workqueue("md_misc", 0, 0); - if (!md_misc_wq) - goto err_misc_wq; - - if ((ret = register_blkdev(MD_MAJOR, "md")) < 0) - goto err_md; - - if ((ret = register_blkdev(0, "mdp")) < 0) - goto err_mdp; - mdp_major = ret; - + if (register_blkdev(MD_MAJOR, "md")) + return -1; + if ((mdp_major=register_blkdev(0, "mdp"))<=0) { + unregister_blkdev(MD_MAJOR, "md"); + return -1; + } blk_register_region(MKDEV(MD_MAJOR, 0), 1UL<hold_active = 0; } - destroy_workqueue(md_misc_wq); - destroy_workqueue(md_wq); } subsys_initcall(md_init); diff --git a/trunk/drivers/md/md.h b/trunk/drivers/md/md.h index d05bab55df4e..112a2c32db0c 100644 --- a/trunk/drivers/md/md.h +++ b/trunk/drivers/md/md.h @@ -331,8 +331,6 @@ struct mddev_s struct attribute_group *to_remove; struct plug_handle *plug; /* if used by personality */ - struct bio_set *bio_set; - /* Generic flush handling. * The last to finish preflush schedules a worker to submit * the rest of the request (without the REQ_FLUSH flag). @@ -497,7 +495,7 @@ extern void md_flush_request(mddev_t *mddev, struct bio *bio); extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, sector_t sector, int size, struct page *page); extern void md_super_wait(mddev_t *mddev); -extern int sync_page_io(mdk_rdev_t *rdev, sector_t sector, int size, +extern int sync_page_io(struct block_device *bdev, sector_t sector, int size, struct page *page, int rw); extern void md_do_sync(mddev_t *mddev); extern void md_new_event(mddev_t *mddev); @@ -519,8 +517,4 @@ extern void md_rdev_init(mdk_rdev_t *rdev); extern void mddev_suspend(mddev_t *mddev); extern void mddev_resume(mddev_t *mddev); -extern struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask, - mddev_t *mddev); -extern struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs, - mddev_t *mddev); #endif /* _MD_MD_H */ diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index 45f8324196ec..378a25894c57 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -100,7 +100,7 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data) * Allocate bios : 1 for reading, n-1 for writing */ for (j = pi->raid_disks ; j-- ; ) { - bio = bio_kmalloc(gfp_flags, RESYNC_PAGES); + bio = bio_alloc(gfp_flags, RESYNC_PAGES); if (!bio) goto out_free_bio; r1_bio->bios[j] = bio; @@ -306,28 +306,6 @@ static void raid1_end_read_request(struct bio *bio, int error) rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev); } -static void r1_bio_write_done(r1bio_t *r1_bio, int vcnt, struct bio_vec *bv, - int behind) -{ - if (atomic_dec_and_test(&r1_bio->remaining)) - { - /* it really is the end of this request */ - if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { - /* free extra copy of the data pages */ - int i = vcnt; - while (i--) - safe_put_page(bv[i].bv_page); - } - /* clear the bitmap if all writes complete successfully */ - bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector, - r1_bio->sectors, - !test_bit(R1BIO_Degraded, &r1_bio->state), - behind); - md_write_end(r1_bio->mddev); - raid_end_bio_io(r1_bio); - } -} - static void raid1_end_write_request(struct bio *bio, int error) { int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); @@ -395,7 +373,21 @@ static void raid1_end_write_request(struct bio *bio, int error) * Let's see if all mirrored write operations have finished * already. */ - r1_bio_write_done(r1_bio, bio->bi_vcnt, bio->bi_io_vec, behind); + if (atomic_dec_and_test(&r1_bio->remaining)) { + if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { + /* free extra copy of the data pages */ + int i = bio->bi_vcnt; + while (i--) + safe_put_page(bio->bi_io_vec[i].bv_page); + } + /* clear the bitmap if all writes complete successfully */ + bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector, + r1_bio->sectors, + !test_bit(R1BIO_Degraded, &r1_bio->state), + behind); + md_write_end(r1_bio->mddev); + raid_end_bio_io(r1_bio); + } if (to_put) bio_put(to_put); @@ -419,13 +411,11 @@ static void raid1_end_write_request(struct bio *bio, int error) static int read_balance(conf_t *conf, r1bio_t *r1_bio) { const sector_t this_sector = r1_bio->sector; + int new_disk = conf->last_used, disk = new_disk; + int wonly_disk = -1; const int sectors = r1_bio->sectors; - int new_disk = -1; - int start_disk; - int i; sector_t new_distance, current_distance; mdk_rdev_t *rdev; - int choose_first; rcu_read_lock(); /* @@ -436,33 +426,54 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio) retry: if (conf->mddev->recovery_cp < MaxSector && (this_sector + sectors >= conf->next_resync)) { - choose_first = 1; - start_disk = 0; - } else { - choose_first = 0; - start_disk = conf->last_used; - } + /* Choose the first operational device, for consistancy */ + new_disk = 0; - /* make sure the disk is operational */ - for (i = 0 ; i < conf->raid_disks ; i++) { - int disk = start_disk + i; - if (disk >= conf->raid_disks) - disk -= conf->raid_disks; + for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev); + r1_bio->bios[new_disk] == IO_BLOCKED || + !rdev || !test_bit(In_sync, &rdev->flags) + || test_bit(WriteMostly, &rdev->flags); + rdev = rcu_dereference(conf->mirrors[++new_disk].rdev)) { - rdev = rcu_dereference(conf->mirrors[disk].rdev); - if (r1_bio->bios[disk] == IO_BLOCKED - || rdev == NULL - || !test_bit(In_sync, &rdev->flags)) - continue; + if (rdev && test_bit(In_sync, &rdev->flags) && + r1_bio->bios[new_disk] != IO_BLOCKED) + wonly_disk = new_disk; - new_disk = disk; - if (!test_bit(WriteMostly, &rdev->flags)) + if (new_disk == conf->raid_disks - 1) { + new_disk = wonly_disk; + break; + } + } + goto rb_out; + } + + + /* make sure the disk is operational */ + for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev); + r1_bio->bios[new_disk] == IO_BLOCKED || + !rdev || !test_bit(In_sync, &rdev->flags) || + test_bit(WriteMostly, &rdev->flags); + rdev = rcu_dereference(conf->mirrors[new_disk].rdev)) { + + if (rdev && test_bit(In_sync, &rdev->flags) && + r1_bio->bios[new_disk] != IO_BLOCKED) + wonly_disk = new_disk; + + if (new_disk <= 0) + new_disk = conf->raid_disks; + new_disk--; + if (new_disk == disk) { + new_disk = wonly_disk; break; + } } - if (new_disk < 0 || choose_first) + if (new_disk < 0) goto rb_out; + disk = new_disk; + /* now disk == new_disk == starting point for search */ + /* * Don't change to another disk for sequential reads: */ @@ -471,21 +482,20 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio) if (this_sector == conf->mirrors[new_disk].head_position) goto rb_out; - current_distance = abs(this_sector - - conf->mirrors[new_disk].head_position); + current_distance = abs(this_sector - conf->mirrors[disk].head_position); + + /* Find the disk whose head is closest */ - /* look for a better disk - i.e. head is closer */ - start_disk = new_disk; - for (i = 1; i < conf->raid_disks; i++) { - int disk = start_disk + 1; - if (disk >= conf->raid_disks) - disk -= conf->raid_disks; + do { + if (disk <= 0) + disk = conf->raid_disks; + disk--; rdev = rcu_dereference(conf->mirrors[disk].rdev); - if (r1_bio->bios[disk] == IO_BLOCKED - || rdev == NULL - || !test_bit(In_sync, &rdev->flags) - || test_bit(WriteMostly, &rdev->flags)) + + if (!rdev || r1_bio->bios[disk] == IO_BLOCKED || + !test_bit(In_sync, &rdev->flags) || + test_bit(WriteMostly, &rdev->flags)) continue; if (!atomic_read(&rdev->nr_pending)) { @@ -497,9 +507,11 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio) current_distance = new_distance; new_disk = disk; } - } + } while (disk != conf->last_used); rb_out: + + if (new_disk >= 0) { rdev = rcu_dereference(conf->mirrors[new_disk].rdev); if (!rdev) @@ -646,7 +658,7 @@ static void raise_barrier(conf_t *conf) /* block any new IO from starting */ conf->barrier++; - /* Now wait for all pending IO to complete */ + /* No wait for all pending IO to complete */ wait_event_lock_irq(conf->wait_barrier, !conf->nr_pending && conf->barrier < RESYNC_DEPTH, conf->resync_lock, @@ -723,26 +735,23 @@ static void unfreeze_array(conf_t *conf) } -/* duplicate the data pages for behind I/O - * We return a list of bio_vec rather than just page pointers - * as it makes freeing easier - */ -static struct bio_vec *alloc_behind_pages(struct bio *bio) +/* duplicate the data pages for behind I/O */ +static struct page **alloc_behind_pages(struct bio *bio) { int i; struct bio_vec *bvec; - struct bio_vec *pages = kzalloc(bio->bi_vcnt * sizeof(struct bio_vec), + struct page **pages = kzalloc(bio->bi_vcnt * sizeof(struct page *), GFP_NOIO); if (unlikely(!pages)) goto do_sync_io; bio_for_each_segment(bvec, bio, i) { - pages[i].bv_page = alloc_page(GFP_NOIO); - if (unlikely(!pages[i].bv_page)) + pages[i] = alloc_page(GFP_NOIO); + if (unlikely(!pages[i])) goto do_sync_io; - memcpy(kmap(pages[i].bv_page) + bvec->bv_offset, + memcpy(kmap(pages[i]) + bvec->bv_offset, kmap(bvec->bv_page) + bvec->bv_offset, bvec->bv_len); - kunmap(pages[i].bv_page); + kunmap(pages[i]); kunmap(bvec->bv_page); } @@ -750,8 +759,8 @@ static struct bio_vec *alloc_behind_pages(struct bio *bio) do_sync_io: if (pages) - for (i = 0; i < bio->bi_vcnt && pages[i].bv_page; i++) - put_page(pages[i].bv_page); + for (i = 0; i < bio->bi_vcnt && pages[i]; i++) + put_page(pages[i]); kfree(pages); PRINTK("%dB behind alloc failed, doing sync I/O\n", bio->bi_size); return NULL; @@ -766,7 +775,8 @@ static int make_request(mddev_t *mddev, struct bio * bio) int i, targets = 0, disks; struct bitmap *bitmap; unsigned long flags; - struct bio_vec *behind_pages = NULL; + struct bio_list bl; + struct page **behind_pages = NULL; const int rw = bio_data_dir(bio); const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA)); @@ -841,7 +851,7 @@ static int make_request(mddev_t *mddev, struct bio * bio) } r1_bio->read_disk = rdisk; - read_bio = bio_clone_mddev(bio, GFP_NOIO, mddev); + read_bio = bio_clone(bio, GFP_NOIO); r1_bio->bios[rdisk] = read_bio; @@ -863,6 +873,13 @@ static int make_request(mddev_t *mddev, struct bio * bio) * bios[x] to bio */ disks = conf->raid_disks; +#if 0 + { static int first=1; + if (first) printk("First Write sector %llu disks %d\n", + (unsigned long long)r1_bio->sector, disks); + first = 0; + } +#endif retry_write: blocked_rdev = NULL; rcu_read_lock(); @@ -920,17 +937,16 @@ static int make_request(mddev_t *mddev, struct bio * bio) (behind_pages = alloc_behind_pages(bio)) != NULL) set_bit(R1BIO_BehindIO, &r1_bio->state); - atomic_set(&r1_bio->remaining, 1); + atomic_set(&r1_bio->remaining, 0); atomic_set(&r1_bio->behind_remaining, 0); - bitmap_startwrite(bitmap, bio->bi_sector, r1_bio->sectors, - test_bit(R1BIO_BehindIO, &r1_bio->state)); + bio_list_init(&bl); for (i = 0; i < disks; i++) { struct bio *mbio; if (!r1_bio->bios[i]) continue; - mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); + mbio = bio_clone(bio, GFP_NOIO); r1_bio->bios[i] = mbio; mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset; @@ -947,29 +963,39 @@ static int make_request(mddev_t *mddev, struct bio * bio) * we clear any unused pointer in the io_vec, rather * than leave them unchanged. This is important * because when we come to free the pages, we won't - * know the original bi_idx, so we just free + * know the originial bi_idx, so we just free * them all */ __bio_for_each_segment(bvec, mbio, j, 0) - bvec->bv_page = behind_pages[j].bv_page; + bvec->bv_page = behind_pages[j]; if (test_bit(WriteMostly, &conf->mirrors[i].rdev->flags)) atomic_inc(&r1_bio->behind_remaining); } atomic_inc(&r1_bio->remaining); - spin_lock_irqsave(&conf->device_lock, flags); - bio_list_add(&conf->pending_bio_list, mbio); - blk_plug_device(mddev->queue); - spin_unlock_irqrestore(&conf->device_lock, flags); + + bio_list_add(&bl, mbio); } - r1_bio_write_done(r1_bio, bio->bi_vcnt, behind_pages, behind_pages != NULL); kfree(behind_pages); /* the behind pages are attached to the bios now */ - /* In case raid1d snuck in to freeze_array */ + bitmap_startwrite(bitmap, bio->bi_sector, r1_bio->sectors, + test_bit(R1BIO_BehindIO, &r1_bio->state)); + spin_lock_irqsave(&conf->device_lock, flags); + bio_list_merge(&conf->pending_bio_list, &bl); + bio_list_init(&bl); + + blk_plug_device(mddev->queue); + spin_unlock_irqrestore(&conf->device_lock, flags); + + /* In case raid1d snuck into freeze_array */ wake_up(&conf->wait_barrier); if (do_sync) md_wakeup_thread(mddev->thread); +#if 0 + while ((bio = bio_list_pop(&bl)) != NULL) + generic_make_request(bio); +#endif return 0; } @@ -1157,7 +1183,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number) err = -EBUSY; goto abort; } - /* Only remove non-faulty devices if recovery + /* Only remove non-faulty devices is recovery * is not possible. */ if (!test_bit(Faulty, &rdev->flags) && @@ -1219,7 +1245,7 @@ static void end_sync_write(struct bio *bio, int error) break; } if (!uptodate) { - sector_t sync_blocks = 0; + int sync_blocks = 0; sector_t s = r1_bio->sector; long sectors_to_go = r1_bio->sectors; /* make sure these bits doesn't get cleared. */ @@ -1362,7 +1388,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) * active, and resync is currently active */ rdev = conf->mirrors[d].rdev; - if (sync_page_io(rdev, + if (sync_page_io(rdev->bdev, sect + rdev->data_offset, s<<9, bio->bi_io_vec[idx].bv_page, @@ -1388,7 +1414,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) continue; rdev = conf->mirrors[d].rdev; atomic_add(s, &rdev->corrected_errors); - if (sync_page_io(rdev, + if (sync_page_io(rdev->bdev, sect + rdev->data_offset, s<<9, bio->bi_io_vec[idx].bv_page, @@ -1403,7 +1429,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) if (r1_bio->bios[d]->bi_end_io != end_sync_read) continue; rdev = conf->mirrors[d].rdev; - if (sync_page_io(rdev, + if (sync_page_io(rdev->bdev, sect + rdev->data_offset, s<<9, bio->bi_io_vec[idx].bv_page, @@ -1487,7 +1513,7 @@ static void fix_read_error(conf_t *conf, int read_disk, rdev = conf->mirrors[d].rdev; if (rdev && test_bit(In_sync, &rdev->flags) && - sync_page_io(rdev, + sync_page_io(rdev->bdev, sect + rdev->data_offset, s<<9, conf->tmppage, READ)) @@ -1513,7 +1539,7 @@ static void fix_read_error(conf_t *conf, int read_disk, rdev = conf->mirrors[d].rdev; if (rdev && test_bit(In_sync, &rdev->flags)) { - if (sync_page_io(rdev, + if (sync_page_io(rdev->bdev, sect + rdev->data_offset, s<<9, conf->tmppage, WRITE) == 0) @@ -1530,7 +1556,7 @@ static void fix_read_error(conf_t *conf, int read_disk, rdev = conf->mirrors[d].rdev; if (rdev && test_bit(In_sync, &rdev->flags)) { - if (sync_page_io(rdev, + if (sync_page_io(rdev->bdev, sect + rdev->data_offset, s<<9, conf->tmppage, READ) == 0) @@ -1620,8 +1646,7 @@ static void raid1d(mddev_t *mddev) mddev->ro ? IO_BLOCKED : NULL; r1_bio->read_disk = disk; bio_put(bio); - bio = bio_clone_mddev(r1_bio->master_bio, - GFP_NOIO, mddev); + bio = bio_clone(r1_bio->master_bio, GFP_NOIO); r1_bio->bios[r1_bio->read_disk] = bio; rdev = conf->mirrors[disk].rdev; if (printk_ratelimit()) @@ -1680,7 +1705,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i int i; int wonly = -1; int write_targets = 0, read_targets = 0; - sector_t sync_blocks; + int sync_blocks; int still_degraded = 0; if (!conf->r1buf_pool) @@ -1730,11 +1755,11 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i msleep_interruptible(1000); bitmap_cond_end_sync(mddev->bitmap, sector_nr); - r1_bio = mempool_alloc(conf->r1buf_pool, GFP_NOIO); raise_barrier(conf); conf->next_resync = sector_nr; + r1_bio = mempool_alloc(conf->r1buf_pool, GFP_NOIO); rcu_read_lock(); /* * If we get a correctably read error during resync or recovery, @@ -1946,6 +1971,7 @@ static conf_t *setup_conf(mddev_t *mddev) init_waitqueue_head(&conf->wait_barrier); bio_list_init(&conf->pending_bio_list); + bio_list_init(&conf->flushing_bio_list); conf->last_used = -1; for (i = 0; i < conf->raid_disks; i++) { diff --git a/trunk/drivers/md/raid1.h b/trunk/drivers/md/raid1.h index cbfdf1a6acd9..adf8cfd73313 100644 --- a/trunk/drivers/md/raid1.h +++ b/trunk/drivers/md/raid1.h @@ -35,6 +35,8 @@ struct r1_private_data_s { struct list_head retry_list; /* queue pending writes and submit them on unplug */ struct bio_list pending_bio_list; + /* queue of writes that have been unplugged */ + struct bio_list flushing_bio_list; /* for use when syncing mirrors: */ diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index c67aa54694ae..f0d082f749be 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -120,7 +120,7 @@ static void * r10buf_pool_alloc(gfp_t gfp_flags, void *data) * Allocate bios. */ for (j = nalloc ; j-- ; ) { - bio = bio_kmalloc(gfp_flags, RESYNC_PAGES); + bio = bio_alloc(gfp_flags, RESYNC_PAGES); if (!bio) goto out_free_bio; r10_bio->devs[j].bio = bio; @@ -801,6 +801,7 @@ static int make_request(mddev_t *mddev, struct bio * bio) const int rw = bio_data_dir(bio); const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); const unsigned long do_fua = (bio->bi_rw & REQ_FUA); + struct bio_list bl; unsigned long flags; mdk_rdev_t *blocked_rdev; @@ -889,7 +890,7 @@ static int make_request(mddev_t *mddev, struct bio * bio) } mirror = conf->mirrors + disk; - read_bio = bio_clone_mddev(bio, GFP_NOIO, mddev); + read_bio = bio_clone(bio, GFP_NOIO); r10_bio->devs[slot].bio = read_bio; @@ -949,16 +950,16 @@ static int make_request(mddev_t *mddev, struct bio * bio) goto retry_write; } - atomic_set(&r10_bio->remaining, 1); - bitmap_startwrite(mddev->bitmap, bio->bi_sector, r10_bio->sectors, 0); + atomic_set(&r10_bio->remaining, 0); + bio_list_init(&bl); for (i = 0; i < conf->copies; i++) { struct bio *mbio; int d = r10_bio->devs[i].devnum; if (!r10_bio->devs[i].bio) continue; - mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); + mbio = bio_clone(bio, GFP_NOIO); r10_bio->devs[i].bio = mbio; mbio->bi_sector = r10_bio->devs[i].addr+ @@ -969,22 +970,22 @@ static int make_request(mddev_t *mddev, struct bio * bio) mbio->bi_private = r10_bio; atomic_inc(&r10_bio->remaining); - spin_lock_irqsave(&conf->device_lock, flags); - bio_list_add(&conf->pending_bio_list, mbio); - blk_plug_device(mddev->queue); - spin_unlock_irqrestore(&conf->device_lock, flags); + bio_list_add(&bl, mbio); } - if (atomic_dec_and_test(&r10_bio->remaining)) { - /* This matches the end of raid10_end_write_request() */ - bitmap_endwrite(r10_bio->mddev->bitmap, r10_bio->sector, - r10_bio->sectors, - !test_bit(R10BIO_Degraded, &r10_bio->state), - 0); + if (unlikely(!atomic_read(&r10_bio->remaining))) { + /* the array is dead */ md_write_end(mddev); raid_end_bio_io(r10_bio); + return 0; } + bitmap_startwrite(mddev->bitmap, bio->bi_sector, r10_bio->sectors, 0); + spin_lock_irqsave(&conf->device_lock, flags); + bio_list_merge(&conf->pending_bio_list, &bl); + blk_plug_device(mddev->queue); + spin_unlock_irqrestore(&conf->device_lock, flags); + /* In case raid10d snuck in to freeze_array */ wake_up(&conf->wait_barrier); @@ -1557,7 +1558,7 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio) test_bit(In_sync, &rdev->flags)) { atomic_inc(&rdev->nr_pending); rcu_read_unlock(); - success = sync_page_io(rdev, + success = sync_page_io(rdev->bdev, r10_bio->devs[sl].addr + sect + rdev->data_offset, s<<9, @@ -1596,7 +1597,7 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio) atomic_inc(&rdev->nr_pending); rcu_read_unlock(); atomic_add(s, &rdev->corrected_errors); - if (sync_page_io(rdev, + if (sync_page_io(rdev->bdev, r10_bio->devs[sl].addr + sect + rdev->data_offset, s<<9, conf->tmppage, WRITE) @@ -1633,7 +1634,7 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio) char b[BDEVNAME_SIZE]; atomic_inc(&rdev->nr_pending); rcu_read_unlock(); - if (sync_page_io(rdev, + if (sync_page_io(rdev->bdev, r10_bio->devs[sl].addr + sect + rdev->data_offset, s<<9, conf->tmppage, @@ -1746,8 +1747,7 @@ static void raid10d(mddev_t *mddev) mdname(mddev), bdevname(rdev->bdev,b), (unsigned long long)r10_bio->sector); - bio = bio_clone_mddev(r10_bio->master_bio, - GFP_NOIO, mddev); + bio = bio_clone(r10_bio->master_bio, GFP_NOIO); r10_bio->devs[r10_bio->read_slot].bio = bio; bio->bi_sector = r10_bio->devs[r10_bio->read_slot].addr + rdev->data_offset; @@ -1820,7 +1820,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i int disk; int i; int max_sync; - sector_t sync_blocks; + int sync_blocks; sector_t sectors_skipped = 0; int chunks_skipped = 0; diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index dc574f303f8b..31140d1259dc 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -3876,9 +3876,9 @@ static int chunk_aligned_read(mddev_t *mddev, struct bio * raid_bio) return 0; } /* - * use bio_clone_mddev to make a copy of the bio + * use bio_clone to make a copy of the bio */ - align_bi = bio_clone_mddev(raid_bio, GFP_NOIO, mddev); + align_bi = bio_clone(raid_bio, GFP_NOIO); if (!align_bi) return 0; /* @@ -4360,7 +4360,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski raid5_conf_t *conf = mddev->private; struct stripe_head *sh; sector_t max_sector = mddev->dev_sectors; - sector_t sync_blocks; + int sync_blocks; int still_degraded = 0; int i; diff --git a/trunk/drivers/misc/ibmasm/ibmasmfs.c b/trunk/drivers/misc/ibmasm/ibmasmfs.c index d2d5d23416dd..0a53500636c9 100644 --- a/trunk/drivers/misc/ibmasm/ibmasmfs.c +++ b/trunk/drivers/misc/ibmasm/ibmasmfs.c @@ -91,10 +91,11 @@ static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root); static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent); -static struct dentry *ibmasmfs_mount(struct file_system_type *fst, - int flags, const char *name, void *data) +static int ibmasmfs_get_super(struct file_system_type *fst, + int flags, const char *name, void *data, + struct vfsmount *mnt) { - return mount_single(fst, flags, data, ibmasmfs_fill_super); + return get_sb_single(fst, flags, data, ibmasmfs_fill_super, mnt); } static const struct super_operations ibmasmfs_s_ops = { @@ -107,7 +108,7 @@ static const struct file_operations *ibmasmfs_dir_ops = &simple_dir_operations; static struct file_system_type ibmasmfs_type = { .owner = THIS_MODULE, .name = "ibmasmfs", - .mount = ibmasmfs_mount, + .get_sb = ibmasmfs_get_super, .kill_sb = kill_litter_super, }; diff --git a/trunk/drivers/misc/kgdbts.c b/trunk/drivers/misc/kgdbts.c index 59c118c19a91..72450237a0f4 100644 --- a/trunk/drivers/misc/kgdbts.c +++ b/trunk/drivers/misc/kgdbts.c @@ -1044,6 +1044,12 @@ static int __init init_kgdbts(void) return configure_kgdbts(); } +static void cleanup_kgdbts(void) +{ + if (configured == 1) + kgdb_unregister_io_module(&kgdbts_io_ops); +} + static int kgdbts_get_char(void) { int val = 0; @@ -1075,8 +1081,10 @@ static int param_set_kgdbts_var(const char *kmessage, struct kernel_param *kp) return 0; } - if (configured == 1) { - printk(KERN_ERR "kgdbts: ERROR: Already configured and running.\n"); + if (kgdb_connected) { + printk(KERN_ERR + "kgdbts: Cannot reconfigure while KGDB is connected.\n"); + return -EBUSY; } @@ -1085,6 +1093,9 @@ static int param_set_kgdbts_var(const char *kmessage, struct kernel_param *kp) if (config[len - 1] == '\n') config[len - 1] = '\0'; + if (configured == 1) + cleanup_kgdbts(); + /* Go and configure with the new params. */ return configure_kgdbts(); } @@ -1112,6 +1123,7 @@ static struct kgdb_io kgdbts_io_ops = { }; module_init(init_kgdbts); +module_exit(cleanup_kgdbts); module_param_call(kgdbts, param_set_kgdbts_var, param_get_string, &kps, 0644); MODULE_PARM_DESC(kgdbts, "[F#|S#][N#]"); MODULE_DESCRIPTION("KGDB Test Suite"); diff --git a/trunk/drivers/mtd/mtdchar.c b/trunk/drivers/mtd/mtdchar.c index a34a0fe14884..5ef45487b65f 100644 --- a/trunk/drivers/mtd/mtdchar.c +++ b/trunk/drivers/mtd/mtdchar.c @@ -1030,15 +1030,17 @@ static const struct file_operations mtd_fops = { #endif }; -static struct dentry *mtd_inodefs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int mtd_inodefs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, + struct vfsmount *mnt) { - return mount_pseudo(fs_type, "mtd_inode:", NULL, MTD_INODE_FS_MAGIC); + return get_sb_pseudo(fs_type, "mtd_inode:", NULL, MTD_INODE_FS_MAGIC, + mnt); } static struct file_system_type mtd_inodefs_type = { .name = "mtd_inodefs", - .mount = mtd_inodefs_mount, + .get_sb = mtd_inodefs_get_sb, .kill_sb = kill_anon_super, }; diff --git a/trunk/drivers/mtd/mtdsuper.c b/trunk/drivers/mtd/mtdsuper.c index 16b02a1fc100..38e2ab07e7a3 100644 --- a/trunk/drivers/mtd/mtdsuper.c +++ b/trunk/drivers/mtd/mtdsuper.c @@ -54,10 +54,11 @@ static int get_sb_mtd_set(struct super_block *sb, void *_mtd) /* * get a superblock on an MTD-backed filesystem */ -static struct dentry *mount_mtd_aux(struct file_system_type *fs_type, int flags, +static int get_sb_mtd_aux(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct mtd_info *mtd, - int (*fill_super)(struct super_block *, void *, int)) + int (*fill_super)(struct super_block *, void *, int), + struct vfsmount *mnt) { struct super_block *sb; int ret; @@ -78,49 +79,57 @@ static struct dentry *mount_mtd_aux(struct file_system_type *fs_type, int flags, ret = fill_super(sb, data, flags & MS_SILENT ? 1 : 0); if (ret < 0) { deactivate_locked_super(sb); - return ERR_PTR(ret); + return ret; } /* go */ sb->s_flags |= MS_ACTIVE; - return dget(sb->s_root); + simple_set_mnt(mnt, sb); + + return 0; /* new mountpoint for an already mounted superblock */ already_mounted: DEBUG(1, "MTDSB: Device %d (\"%s\") is already mounted\n", mtd->index, mtd->name); - put_mtd_device(mtd); - return dget(sb->s_root); + simple_set_mnt(mnt, sb); + ret = 0; + goto out_put; out_error: + ret = PTR_ERR(sb); +out_put: put_mtd_device(mtd); - return ERR_CAST(sb); + return ret; } /* * get a superblock on an MTD-backed filesystem by MTD device number */ -static struct dentry *mount_mtd_nr(struct file_system_type *fs_type, int flags, +static int get_sb_mtd_nr(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, int mtdnr, - int (*fill_super)(struct super_block *, void *, int)) + int (*fill_super)(struct super_block *, void *, int), + struct vfsmount *mnt) { struct mtd_info *mtd; mtd = get_mtd_device(NULL, mtdnr); if (IS_ERR(mtd)) { DEBUG(0, "MTDSB: Device #%u doesn't appear to exist\n", mtdnr); - return ERR_CAST(mtd); + return PTR_ERR(mtd); } - return mount_mtd_aux(fs_type, flags, dev_name, data, mtd, fill_super); + return get_sb_mtd_aux(fs_type, flags, dev_name, data, mtd, fill_super, + mnt); } /* * set up an MTD-based superblock */ -struct dentry *mount_mtd(struct file_system_type *fs_type, int flags, +int get_sb_mtd(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, - int (*fill_super)(struct super_block *, void *, int)) + int (*fill_super)(struct super_block *, void *, int), + struct vfsmount *mnt) { #ifdef CONFIG_BLOCK struct block_device *bdev; @@ -129,7 +138,7 @@ struct dentry *mount_mtd(struct file_system_type *fs_type, int flags, int mtdnr; if (!dev_name) - return ERR_PTR(-EINVAL); + return -EINVAL; DEBUG(2, "MTDSB: dev_name \"%s\"\n", dev_name); @@ -147,10 +156,10 @@ struct dentry *mount_mtd(struct file_system_type *fs_type, int flags, mtd = get_mtd_device_nm(dev_name + 4); if (!IS_ERR(mtd)) - return mount_mtd_aux( + return get_sb_mtd_aux( fs_type, flags, dev_name, data, mtd, - fill_super); + fill_super, mnt); printk(KERN_NOTICE "MTD:" " MTD device with name \"%s\" not found.\n", @@ -165,9 +174,9 @@ struct dentry *mount_mtd(struct file_system_type *fs_type, int flags, /* It was a valid number */ DEBUG(1, "MTDSB: mtd%%d, mtdnr %d\n", mtdnr); - return mount_mtd_nr(fs_type, flags, + return get_sb_mtd_nr(fs_type, flags, dev_name, data, - mtdnr, fill_super); + mtdnr, fill_super, mnt); } } } @@ -180,7 +189,7 @@ struct dentry *mount_mtd(struct file_system_type *fs_type, int flags, if (IS_ERR(bdev)) { ret = PTR_ERR(bdev); DEBUG(1, "MTDSB: lookup_bdev() returned %d\n", ret); - return ERR_PTR(ret); + return ret; } DEBUG(1, "MTDSB: lookup_bdev() returned 0\n"); @@ -193,7 +202,8 @@ struct dentry *mount_mtd(struct file_system_type *fs_type, int flags, if (major != MTD_BLOCK_MAJOR) goto not_an_MTD_device; - return mount_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super); + return get_sb_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super, + mnt); not_an_MTD_device: #endif /* CONFIG_BLOCK */ @@ -202,10 +212,10 @@ struct dentry *mount_mtd(struct file_system_type *fs_type, int flags, printk(KERN_NOTICE "MTD: Attempt to mount non-MTD device \"%s\"\n", dev_name); - return ERR_PTR(-EINVAL); + return -EINVAL; } -EXPORT_SYMBOL_GPL(mount_mtd); +EXPORT_SYMBOL_GPL(get_sb_mtd); /* * destroy an MTD-based superblock diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index f6668cdaac85..9334539ebf75 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -2541,7 +2541,6 @@ source "drivers/net/stmmac/Kconfig" config PCH_GBE tristate "PCH Gigabit Ethernet" depends on PCI - select MII ---help--- This is a gigabit ethernet driver for Topcliff PCH. Topcliff PCH is the platform controller hub that is used in Intel's diff --git a/trunk/drivers/net/atarilance.c b/trunk/drivers/net/atarilance.c index 8cb27cb7bca1..3134e5326231 100644 --- a/trunk/drivers/net/atarilance.c +++ b/trunk/drivers/net/atarilance.c @@ -407,7 +407,7 @@ static noinline int __init addr_accessible(volatile void *regp, int wordflag, int writeflag) { int ret; - unsigned long flags; + long flags; long *vbr, save_berr; local_irq_save(flags); diff --git a/trunk/drivers/net/cxgb3/cxgb3_main.c b/trunk/drivers/net/cxgb3/cxgb3_main.c index 407d4e272075..4e3c12371aae 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_main.c +++ b/trunk/drivers/net/cxgb3/cxgb3_main.c @@ -3301,6 +3301,7 @@ static int __devinit init_one(struct pci_dev *pdev, pi->rx_offload = T3_RX_CSUM | T3_LRO; pi->port_id = i; netif_carrier_off(netdev); + netif_tx_stop_all_queues(netdev); netdev->irq = pdev->irq; netdev->mem_start = mmio_start; netdev->mem_end = mmio_start + mmio_len - 1; @@ -3341,7 +3342,6 @@ static int __devinit init_one(struct pci_dev *pdev, adapter->name = adapter->port[i]->name; __set_bit(i, &adapter->registered_device_map); - netif_tx_stop_all_queues(adapter->port[i]); } } if (!adapter->registered_device_map) { diff --git a/trunk/drivers/net/cxgb3/sge.c b/trunk/drivers/net/cxgb3/sge.c index f9f6645b2e61..5d72bda54389 100644 --- a/trunk/drivers/net/cxgb3/sge.c +++ b/trunk/drivers/net/cxgb3/sge.c @@ -296,10 +296,8 @@ static void free_tx_desc(struct adapter *adapter, struct sge_txq *q, if (d->skb) { /* an SGL is present */ if (need_unmap) unmap_skb(d->skb, q, cidx, pdev); - if (d->eop) { + if (d->eop) kfree_skb(d->skb); - d->skb = NULL; - } } ++d; if (++cidx == q->size) { diff --git a/trunk/drivers/net/e1000e/82571.c b/trunk/drivers/net/e1000e/82571.c index 7236f1a53ba0..ca663f19d7df 100644 --- a/trunk/drivers/net/e1000e/82571.c +++ b/trunk/drivers/net/e1000e/82571.c @@ -52,10 +52,6 @@ (ID_LED_DEF1_DEF2)) #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 -#define E1000_BASE1000T_STATUS 10 -#define E1000_IDLE_ERROR_COUNT_MASK 0xFF -#define E1000_RECEIVE_ERROR_COUNTER 21 -#define E1000_RECEIVE_ERROR_MAX 0xFFFF #define E1000_NVM_INIT_CTRL2_MNGM 0x6000 /* Manageability Operation Mode mask */ @@ -1246,39 +1242,6 @@ static s32 e1000_led_on_82574(struct e1000_hw *hw) return 0; } -/** - * e1000_check_phy_82574 - check 82574 phy hung state - * @hw: pointer to the HW structure - * - * Returns whether phy is hung or not - **/ -bool e1000_check_phy_82574(struct e1000_hw *hw) -{ - u16 status_1kbt = 0; - u16 receive_errors = 0; - bool phy_hung = false; - s32 ret_val = 0; - - /* - * Read PHY Receive Error counter first, if its is max - all F's then - * read the Base1000T status register If both are max then PHY is hung. - */ - ret_val = e1e_rphy(hw, E1000_RECEIVE_ERROR_COUNTER, &receive_errors); - - if (ret_val) - goto out; - if (receive_errors == E1000_RECEIVE_ERROR_MAX) { - ret_val = e1e_rphy(hw, E1000_BASE1000T_STATUS, &status_1kbt); - if (ret_val) - goto out; - if ((status_1kbt & E1000_IDLE_ERROR_COUNT_MASK) == - E1000_IDLE_ERROR_COUNT_MASK) - phy_hung = true; - } -out: - return phy_hung; -} - /** * e1000_setup_link_82571 - Setup flow control and link settings * @hw: pointer to the HW structure @@ -1896,7 +1859,6 @@ struct e1000_info e1000_82574_info = { | FLAG_HAS_SMART_POWER_DOWN | FLAG_HAS_AMT | FLAG_HAS_CTRLEXT_ON_LOAD, - .flags2 = FLAG2_CHECK_PHY_HANG, .pba = 36, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, diff --git a/trunk/drivers/net/e1000e/e1000.h b/trunk/drivers/net/e1000e/e1000.h index fdc67fead4ea..cee882dd67bf 100644 --- a/trunk/drivers/net/e1000e/e1000.h +++ b/trunk/drivers/net/e1000e/e1000.h @@ -397,7 +397,6 @@ struct e1000_adapter { struct work_struct print_hang_task; bool idle_check; - int phy_hang_count; }; struct e1000_info { @@ -455,7 +454,6 @@ struct e1000_info { #define FLAG2_HAS_EEE (1 << 5) #define FLAG2_DMA_BURST (1 << 6) #define FLAG2_DISABLE_AIM (1 << 8) -#define FLAG2_CHECK_PHY_HANG (1 << 9) #define E1000_RX_DESC_PS(R, i) \ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) @@ -633,7 +631,6 @@ extern s32 e1000_get_phy_info_ife(struct e1000_hw *hw); extern s32 e1000_check_polarity_ife(struct e1000_hw *hw); extern s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw); extern s32 e1000_check_polarity_igp(struct e1000_hw *hw); -extern bool e1000_check_phy_82574(struct e1000_hw *hw); static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw) { diff --git a/trunk/drivers/net/e1000e/netdev.c b/trunk/drivers/net/e1000e/netdev.c index c4ca1629f532..ec8cf3f51423 100644 --- a/trunk/drivers/net/e1000e/netdev.c +++ b/trunk/drivers/net/e1000e/netdev.c @@ -4098,25 +4098,6 @@ static void e1000e_enable_receives(struct e1000_adapter *adapter) } } -static void e1000e_check_82574_phy_workaround(struct e1000_adapter *adapter) -{ - struct e1000_hw *hw = &adapter->hw; - - /* - * With 82574 controllers, PHY needs to be checked periodically - * for hung state and reset, if two calls return true - */ - if (e1000_check_phy_82574(hw)) - adapter->phy_hang_count++; - else - adapter->phy_hang_count = 0; - - if (adapter->phy_hang_count > 1) { - adapter->phy_hang_count = 0; - schedule_work(&adapter->reset_task); - } -} - /** * e1000_watchdog - Timer Call-back * @data: pointer to adapter cast into an unsigned long @@ -4352,9 +4333,6 @@ static void e1000_watchdog_task(struct work_struct *work) if (e1000e_get_laa_state_82571(hw)) e1000e_rar_set(hw, adapter->hw.mac.addr, 0); - if (adapter->flags2 & FLAG2_CHECK_PHY_HANG) - e1000e_check_82574_phy_workaround(adapter); - /* Reset the timer */ if (!test_bit(__E1000_DOWN, &adapter->state)) mod_timer(&adapter->watchdog_timer, @@ -4882,11 +4860,8 @@ static void e1000_reset_task(struct work_struct *work) struct e1000_adapter *adapter; adapter = container_of(work, struct e1000_adapter, reset_task); - if (!((adapter->flags & FLAG_RX_NEEDS_RESTART) && - (adapter->flags & FLAG_RX_RESTART_NOW))) { - e1000e_dump(adapter); - e_err("Reset adapter\n"); - } + e1000e_dump(adapter); + e_err("Reset adapter\n"); e1000e_reinit_locked(adapter); } diff --git a/trunk/drivers/net/igb/igb_main.c b/trunk/drivers/net/igb/igb_main.c index 892d196f17ac..14db09e2fa8b 100644 --- a/trunk/drivers/net/igb/igb_main.c +++ b/trunk/drivers/net/igb/igb_main.c @@ -4107,6 +4107,7 @@ static inline int igb_maybe_stop_tx(struct igb_ring *tx_ring, int size) netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb, struct igb_ring *tx_ring) { + struct igb_adapter *adapter = netdev_priv(tx_ring->netdev); int tso = 0, count; u32 tx_flags = 0; u16 first; diff --git a/trunk/drivers/net/igbvf/netdev.c b/trunk/drivers/net/igbvf/netdev.c index 28af019c97bb..ebfaa68ee630 100644 --- a/trunk/drivers/net/igbvf/netdev.c +++ b/trunk/drivers/net/igbvf/netdev.c @@ -2783,15 +2783,15 @@ static int __devinit igbvf_probe(struct pci_dev *pdev, /* reset the hardware with the new settings */ igbvf_reset(adapter); + /* tell the stack to leave us alone until igbvf_open() is called */ + netif_carrier_off(netdev); + netif_stop_queue(netdev); + strcpy(netdev->name, "eth%d"); err = register_netdev(netdev); if (err) goto err_hw_init; - /* tell the stack to leave us alone until igbvf_open() is called */ - netif_carrier_off(netdev); - netif_stop_queue(netdev); - igbvf_print_device_info(adapter); igbvf_initialize_last_counter_stats(adapter); diff --git a/trunk/drivers/net/ixgb/ixgb_main.c b/trunk/drivers/net/ixgb/ixgb_main.c index caa8192fff2a..666207a9c039 100644 --- a/trunk/drivers/net/ixgb/ixgb_main.c +++ b/trunk/drivers/net/ixgb/ixgb_main.c @@ -533,7 +533,6 @@ ixgb_remove(struct pci_dev *pdev) pci_release_regions(pdev); free_netdev(netdev); - pci_disable_device(pdev); } /** diff --git a/trunk/drivers/net/ixgbe/ixgbe_dcb.c b/trunk/drivers/net/ixgbe/ixgbe_dcb.c index 0d44c6470ca3..8bb9ddb6dffe 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_dcb.c +++ b/trunk/drivers/net/ixgbe/ixgbe_dcb.c @@ -43,12 +43,9 @@ * ixgbe_dcb_check_config(). */ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config, - int max_frame, u8 direction) + u8 direction) { struct tc_bw_alloc *p; - int min_credit; - int min_multiplier; - int min_percent = 100; s32 ret_val = 0; /* Initialization values default for Tx settings */ u32 credit_refill = 0; @@ -62,31 +59,6 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config, goto out; } - min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) / - DCB_CREDIT_QUANTUM; - - /* Find smallest link percentage */ - for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { - p = &dcb_config->tc_config[i].path[direction]; - bw_percent = dcb_config->bw_percentage[direction][p->bwg_id]; - link_percentage = p->bwg_percent; - - link_percentage = (link_percentage * bw_percent) / 100; - - if (link_percentage && link_percentage < min_percent) - min_percent = link_percentage; - } - - /* - * The ratio between traffic classes will control the bandwidth - * percentages seen on the wire. To calculate this ratio we use - * a multiplier. It is required that the refill credits must be - * larger than the max frame size so here we find the smallest - * multiplier that will allow all bandwidth percentages to be - * greater than the max frame size. - */ - min_multiplier = (min_credit / min_percent) + 1; - /* Find out the link percentage for each TC first */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { p = &dcb_config->tc_config[i].path[direction]; @@ -101,9 +73,8 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config, /* Save link_percentage for reference */ p->link_percent = (u8)link_percentage; - /* Calculate credit refill ratio using multiplier */ - credit_refill = min(link_percentage * min_multiplier, - MAX_CREDIT_REFILL); + /* Calculate credit refill and save it */ + credit_refill = link_percentage * MINIMUM_CREDIT_REFILL; p->data_credits_refill = (u16)credit_refill; /* Calculate maximum credit for the TC */ @@ -114,8 +85,8 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config, * of a TC is too small, the maximum credit may not be * enough to send out a jumbo frame in data plane arbitration. */ - if (credit_max && (credit_max < min_credit)) - credit_max = min_credit; + if (credit_max && (credit_max < MINIMUM_CREDIT_FOR_JUMBO)) + credit_max = MINIMUM_CREDIT_FOR_JUMBO; if (direction == DCB_TX_CONFIG) { /* diff --git a/trunk/drivers/net/ixgbe/ixgbe_dcb.h b/trunk/drivers/net/ixgbe/ixgbe_dcb.h index 0208a87b129e..eb1059f09da0 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_dcb.h +++ b/trunk/drivers/net/ixgbe/ixgbe_dcb.h @@ -150,14 +150,15 @@ struct ixgbe_dcb_config { /* DCB driver APIs */ /* DCB credits calculation */ -s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *, int, u8); +s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *, u8); /* DCB hw initialization */ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, struct ixgbe_dcb_config *); /* DCB definitions for credit calculation */ -#define DCB_CREDIT_QUANTUM 64 /* DCB Quantum */ #define MAX_CREDIT_REFILL 511 /* 0x1FF * 64B = 32704B */ +#define MINIMUM_CREDIT_REFILL 5 /* 5*64B = 320B */ +#define MINIMUM_CREDIT_FOR_JUMBO 145 /* 145= UpperBound((9*1024+54)/64B) for 9KB jumbo frame */ #define DCB_MAX_TSO_SIZE (32*1024) /* MAX TSO packet size supported in DCB mode */ #define MINIMUM_CREDIT_FOR_TSO (DCB_MAX_TSO_SIZE/64 + 1) /* 513 for 32KB TSO packet */ #define MAX_CREDIT 4095 /* Maximum credit supported: 256KB * 1204 / 64B */ diff --git a/trunk/drivers/net/ixgbe/ixgbe_dcb_82599.c b/trunk/drivers/net/ixgbe/ixgbe_dcb_82599.c index 05f224715073..67c219f86c3a 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/trunk/drivers/net/ixgbe/ixgbe_dcb_82599.c @@ -397,11 +397,6 @@ static s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw) reg &= ~IXGBE_RTTDCS_ARBDIS; IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg); - /* Enable Security TX Buffer IFG for DCB */ - reg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG); - reg |= IXGBE_SECTX_DCB; - IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg); - return 0; } diff --git a/trunk/drivers/net/ixgbe/ixgbe_dcb_82599.h b/trunk/drivers/net/ixgbe/ixgbe_dcb_82599.h index 3841649fb954..18d7fbf6c292 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_dcb_82599.h +++ b/trunk/drivers/net/ixgbe/ixgbe_dcb_82599.h @@ -95,9 +95,6 @@ #define IXGBE_TXPBTHRESH_DCB 0xA /* THRESH value for DCB mode */ -/* SECTXMINIFG DCB */ -#define IXGBE_SECTX_DCB 0x00001F00 /* DCB TX Buffer IFG */ - /* DCB hardware-specific driver APIs */ diff --git a/trunk/drivers/net/ixgbe/ixgbe_main.c b/trunk/drivers/net/ixgbe/ixgbe_main.c index 2bd3eb4ee5a1..f85631263af8 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ixgbe/ixgbe_main.c @@ -3347,7 +3347,6 @@ static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter) static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; - int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN; u32 txdctl; int i, j; @@ -3360,15 +3359,8 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) if (hw->mac.type == ixgbe_mac_82598EB) netif_set_gso_max_size(adapter->netdev, 32768); -#ifdef CONFIG_FCOE - if (adapter->netdev->features & NETIF_F_FCOE_MTU) - max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); -#endif - - ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, max_frame, - DCB_TX_CONFIG); - ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, max_frame, - DCB_RX_CONFIG); + ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_TX_CONFIG); + ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_RX_CONFIG); /* reconfigure the hardware */ ixgbe_dcb_hw_config(&adapter->hw, &adapter->dcb_cfg); diff --git a/trunk/drivers/net/lib8390.c b/trunk/drivers/net/lib8390.c index e7030ceb178b..316bb70775b1 100644 --- a/trunk/drivers/net/lib8390.c +++ b/trunk/drivers/net/lib8390.c @@ -1077,6 +1077,7 @@ static void __NS8390_init(struct net_device *dev, int startp) ei_outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG); ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); + netif_start_queue(dev); ei_local->tx1 = ei_local->tx2 = 0; ei_local->txing = 0; diff --git a/trunk/drivers/net/netxen/netxen_nic_ctx.c b/trunk/drivers/net/netxen/netxen_nic_ctx.c index f7d06cbc70ae..12612127a087 100644 --- a/trunk/drivers/net/netxen/netxen_nic_ctx.c +++ b/trunk/drivers/net/netxen/netxen_nic_ctx.c @@ -254,6 +254,19 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) return err; } +static void +nx_fw_cmd_reset_ctx(struct netxen_adapter *adapter) +{ + + netxen_issue_cmd(adapter, adapter->ahw.pci_func, NXHAL_VERSION, + adapter->ahw.pci_func, NX_DESTROY_CTX_RESET, 0, + NX_CDRP_CMD_DESTROY_RX_CTX); + + netxen_issue_cmd(adapter, adapter->ahw.pci_func, NXHAL_VERSION, + adapter->ahw.pci_func, NX_DESTROY_CTX_RESET, 0, + NX_CDRP_CMD_DESTROY_TX_CTX); +} + static void nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter) { @@ -685,6 +698,8 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) { if (test_and_set_bit(__NX_FW_ATTACHED, &adapter->state)) goto done; + if (reset_devices) + nx_fw_cmd_reset_ctx(adapter); err = nx_fw_cmd_create_rx_ctx(adapter); if (err) goto err_out_free; diff --git a/trunk/drivers/net/netxen/netxen_nic_main.c b/trunk/drivers/net/netxen/netxen_nic_main.c index 35ae1aa12896..50820beac3aa 100644 --- a/trunk/drivers/net/netxen/netxen_nic_main.c +++ b/trunk/drivers/net/netxen/netxen_nic_main.c @@ -1356,13 +1356,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } - if (reset_devices) { - if (adapter->portnum == 0) { - NXWR32(adapter, NX_CRB_DEV_REF_COUNT, 0); - adapter->need_fw_reset = 1; - } - } - err = netxen_start_firmware(adapter); if (err) goto err_out_decr_ref; diff --git a/trunk/drivers/net/stmmac/stmmac_main.c b/trunk/drivers/net/stmmac/stmmac_main.c index 06bc6034ce81..823b9e6431d5 100644 --- a/trunk/drivers/net/stmmac/stmmac_main.c +++ b/trunk/drivers/net/stmmac/stmmac_main.c @@ -337,19 +337,33 @@ static int stmmac_init_phy(struct net_device *dev) return 0; } -static inline void stmmac_enable_mac(void __iomem *ioaddr) +static inline void stmmac_mac_enable_rx(void __iomem *ioaddr) { u32 value = readl(ioaddr + MAC_CTRL_REG); + value |= MAC_RNABLE_RX; + /* Set the RE (receive enable bit into the MAC CTRL register). */ + writel(value, ioaddr + MAC_CTRL_REG); +} - value |= MAC_RNABLE_RX | MAC_ENABLE_TX; +static inline void stmmac_mac_enable_tx(void __iomem *ioaddr) +{ + u32 value = readl(ioaddr + MAC_CTRL_REG); + value |= MAC_ENABLE_TX; + /* Set the TE (transmit enable bit into the MAC CTRL register). */ writel(value, ioaddr + MAC_CTRL_REG); } -static inline void stmmac_disable_mac(void __iomem *ioaddr) +static inline void stmmac_mac_disable_rx(void __iomem *ioaddr) { u32 value = readl(ioaddr + MAC_CTRL_REG); + value &= ~MAC_RNABLE_RX; + writel(value, ioaddr + MAC_CTRL_REG); +} - value &= ~(MAC_ENABLE_TX | MAC_RNABLE_RX); +static inline void stmmac_mac_disable_tx(void __iomem *ioaddr) +{ + u32 value = readl(ioaddr + MAC_CTRL_REG); + value &= ~MAC_ENABLE_TX; writel(value, ioaddr + MAC_CTRL_REG); } @@ -843,7 +857,8 @@ static int stmmac_open(struct net_device *dev) writel(0xffffffff, priv->ioaddr + MMC_LOW_INTR_MASK); /* Enable the MAC Rx/Tx */ - stmmac_enable_mac(priv->ioaddr); + stmmac_mac_enable_rx(priv->ioaddr); + stmmac_mac_enable_tx(priv->ioaddr); /* Set the HW DMA mode and the COE */ stmmac_dma_operation_mode(priv); @@ -913,8 +928,9 @@ static int stmmac_release(struct net_device *dev) /* Release and free the Rx/Tx resources */ free_dma_desc_resources(priv); - /* Disable the MAC Rx/Tx */ - stmmac_disable_mac(priv->ioaddr); + /* Disable the MAC core */ + stmmac_mac_disable_tx(priv->ioaddr); + stmmac_mac_disable_rx(priv->ioaddr); netif_carrier_off(dev); @@ -1771,7 +1787,8 @@ static int stmmac_dvr_remove(struct platform_device *pdev) priv->hw->dma->stop_rx(priv->ioaddr); priv->hw->dma->stop_tx(priv->ioaddr); - stmmac_disable_mac(priv->ioaddr); + stmmac_mac_disable_rx(priv->ioaddr); + stmmac_mac_disable_tx(priv->ioaddr); netif_carrier_off(ndev); @@ -1822,11 +1839,13 @@ static int stmmac_suspend(struct platform_device *pdev, pm_message_t state) dis_ic); priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); + stmmac_mac_disable_tx(priv->ioaddr); + /* Enable Power down mode by programming the PMT regs */ if (device_can_wakeup(priv->device)) priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); else - stmmac_disable_mac(priv->ioaddr); + stmmac_mac_disable_rx(priv->ioaddr); } else { priv->shutdown = 1; /* Although this can appear slightly redundant it actually @@ -1867,7 +1886,8 @@ static int stmmac_resume(struct platform_device *pdev) netif_device_attach(dev); /* Enable the MAC and DMA */ - stmmac_enable_mac(priv->ioaddr); + stmmac_mac_enable_rx(priv->ioaddr); + stmmac_mac_enable_tx(priv->ioaddr); priv->hw->dma->start_tx(priv->ioaddr); priv->hw->dma->start_rx(priv->ioaddr); diff --git a/trunk/drivers/net/wireless/ath/ath5k/attach.c b/trunk/drivers/net/wireless/ath/ath5k/attach.c index fbe8aca975d8..cd0b14a0a93a 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/attach.c +++ b/trunk/drivers/net/wireless/ath/ath5k/attach.c @@ -139,12 +139,12 @@ int ath5k_hw_attach(struct ath5k_softc *sc) /* Fill the ath5k_hw struct with the needed functions */ ret = ath5k_hw_init_desc_functions(ah); if (ret) - goto err; + goto err_free; /* Bring device out of sleep and reset its units */ ret = ath5k_hw_nic_wakeup(ah, 0, true); if (ret) - goto err; + goto err_free; /* Get MAC, PHY and RADIO revisions */ ah->ah_mac_srev = srev; @@ -234,7 +234,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) } else { ATH5K_ERR(sc, "Couldn't identify radio revision.\n"); ret = -ENODEV; - goto err; + goto err_free; } } @@ -244,7 +244,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) (srev < AR5K_SREV_AR2425)) { ATH5K_ERR(sc, "Device not yet supported.\n"); ret = -ENODEV; - goto err; + goto err_free; } /* @@ -252,7 +252,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) */ ret = ath5k_hw_post(ah); if (ret) - goto err; + goto err_free; /* Enable pci core retry fix on Hainan (5213A) and later chips */ if (srev >= AR5K_SREV_AR5213A) @@ -265,7 +265,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) ret = ath5k_eeprom_init(ah); if (ret) { ATH5K_ERR(sc, "unable to init EEPROM\n"); - goto err; + goto err_free; } ee = &ah->ah_capabilities.cap_eeprom; @@ -307,7 +307,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) if (ret) { ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n", sc->pdev->device); - goto err; + goto err_free; } /* Crypto settings */ @@ -341,7 +341,8 @@ int ath5k_hw_attach(struct ath5k_softc *sc) ath5k_hw_set_ledstate(ah, AR5K_LED_INIT); return 0; -err: +err_free: + kfree(ah); return ret; } diff --git a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h index 9b8e7e3fcebd..973c919fdd27 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h @@ -310,7 +310,7 @@ struct ath_rx { u8 rxotherant; u32 *rxlink; unsigned int rxfilter; - spinlock_t pcu_lock; + spinlock_t rxflushlock; spinlock_t rxbuflock; struct list_head rxbuf; struct ath_descdma rxdma; diff --git a/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c b/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c index 6576f683dba0..728d904c74d7 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -801,16 +801,10 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) } kfree(buf); - switch (hif_dev->device_id) { - case 0x7010: - case 0x7015: - case 0x9018: + if ((hif_dev->device_id == 0x7010) || (hif_dev->device_id == 0x7015)) firm_offset = AR7010_FIRMWARE_TEXT; - break; - default: + else firm_offset = AR9271_FIRMWARE_TEXT; - break; - } /* * Issue FW download complete command to firmware. diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index b52f1cf8a603..c6ec800d7a6b 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -241,9 +241,6 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, */ ath9k_hw_set_interrupts(ah, 0); ath_drain_all_txq(sc, false); - - spin_lock_bh(&sc->rx.pcu_lock); - stopped = ath_stoprecv(sc); /* XXX: do not flush receive queue here. We don't want @@ -271,7 +268,6 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, "reset status %d\n", channel->center_freq, r); spin_unlock_bh(&sc->sc_resetlock); - spin_unlock_bh(&sc->rx.pcu_lock); goto ps_restore; } spin_unlock_bh(&sc->sc_resetlock); @@ -280,12 +276,9 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, ath_print(common, ATH_DBG_FATAL, "Unable to restart recv logic\n"); r = -EIO; - spin_unlock_bh(&sc->rx.pcu_lock); goto ps_restore; } - spin_unlock_bh(&sc->rx.pcu_lock); - ath_update_txpow(sc); ath9k_hw_set_interrupts(ah, ah->imask); @@ -620,7 +613,7 @@ void ath9k_tasklet(unsigned long data) rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN); if (status & rxmask) { - spin_lock_bh(&sc->rx.pcu_lock); + spin_lock_bh(&sc->rx.rxflushlock); /* Check for high priority Rx first */ if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && @@ -628,7 +621,7 @@ void ath9k_tasklet(unsigned long data) ath_rx_tasklet(sc, 0, true); ath_rx_tasklet(sc, 0, false); - spin_unlock_bh(&sc->rx.pcu_lock); + spin_unlock_bh(&sc->rx.rxflushlock); } if (status & ATH9K_INT_TX) { @@ -883,7 +876,6 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) if (!ah->curchan) ah->curchan = ath_get_curchannel(sc, sc->hw); - spin_lock_bh(&sc->rx.pcu_lock); spin_lock_bh(&sc->sc_resetlock); r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); if (r) { @@ -898,10 +890,8 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) if (ath_startrecv(sc) != 0) { ath_print(common, ATH_DBG_FATAL, "Unable to restart recv logic\n"); - spin_unlock_bh(&sc->rx.pcu_lock); return; } - spin_unlock_bh(&sc->rx.pcu_lock); if (sc->sc_flags & SC_OP_BEACONS) ath_beacon_config(sc, NULL); /* restart beacons */ @@ -940,9 +930,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) ath9k_hw_set_interrupts(ah, 0); ath_drain_all_txq(sc, false); /* clear pending tx frames */ - - spin_lock_bh(&sc->rx.pcu_lock); - ath_stoprecv(sc); /* turn off frame recv */ ath_flushrecv(sc); /* flush recv queue */ @@ -960,9 +947,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) spin_unlock_bh(&sc->sc_resetlock); ath9k_hw_phy_disable(ah); - - spin_unlock_bh(&sc->rx.pcu_lock); - ath9k_hw_configpcipowersave(ah, 1, 1); ath9k_ps_restore(sc); ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); @@ -982,9 +966,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) ath9k_hw_set_interrupts(ah, 0); ath_drain_all_txq(sc, retry_tx); - - spin_lock_bh(&sc->rx.pcu_lock); - ath_stoprecv(sc); ath_flushrecv(sc); @@ -999,8 +980,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) ath_print(common, ATH_DBG_FATAL, "Unable to start recv logic\n"); - spin_unlock_bh(&sc->rx.pcu_lock); - /* * We may be doing a reset in response to a request * that changes the channel so update any state that @@ -1163,7 +1142,6 @@ static int ath9k_start(struct ieee80211_hw *hw) * be followed by initialization of the appropriate bits * and then setup of the interrupt mask. */ - spin_lock_bh(&sc->rx.pcu_lock); spin_lock_bh(&sc->sc_resetlock); r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); if (r) { @@ -1172,7 +1150,6 @@ static int ath9k_start(struct ieee80211_hw *hw) "(freq %u MHz)\n", r, curchan->center_freq); spin_unlock_bh(&sc->sc_resetlock); - spin_unlock_bh(&sc->rx.pcu_lock); goto mutex_unlock; } spin_unlock_bh(&sc->sc_resetlock); @@ -1194,10 +1171,8 @@ static int ath9k_start(struct ieee80211_hw *hw) ath_print(common, ATH_DBG_FATAL, "Unable to start recv logic\n"); r = -EIO; - spin_unlock_bh(&sc->rx.pcu_lock); goto mutex_unlock; } - spin_unlock_bh(&sc->rx.pcu_lock); /* Setup our intr mask. */ ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL | @@ -1396,14 +1371,12 @@ static void ath9k_stop(struct ieee80211_hw *hw) * before setting the invalid flag. */ ath9k_hw_set_interrupts(ah, 0); - spin_lock_bh(&sc->rx.pcu_lock); if (!(sc->sc_flags & SC_OP_INVALID)) { ath_drain_all_txq(sc, false); ath_stoprecv(sc); ath9k_hw_phy_disable(ah); } else sc->rx.rxlink = NULL; - spin_unlock_bh(&sc->rx.pcu_lock); /* disable HAL and put h/w to sleep */ ath9k_hw_disable(ah); diff --git a/trunk/drivers/net/wireless/ath/ath9k/rc.c b/trunk/drivers/net/wireless/ath/ath9k/rc.c index 89978d71617f..0cee90cf8dc9 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/rc.c +++ b/trunk/drivers/net/wireless/ath/ath9k/rc.c @@ -527,7 +527,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, for (i = 0; i < rateset->rs_nrates; i++) { for (j = 0; j < rate_table->rate_cnt; j++) { u32 phy = rate_table->info[j].phy; - u16 rate_flags = rate_table->info[j].rate_flags; + u16 rate_flags = rate_table->info[i].rate_flags; u8 rate = rateset->rs_rates[i]; u8 dot11rate = rate_table->info[j].dot11rate; diff --git a/trunk/drivers/net/wireless/ath/ath9k/recv.c b/trunk/drivers/net/wireless/ath/ath9k/recv.c index fddb0129bb57..fe73fc50082a 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/recv.c +++ b/trunk/drivers/net/wireless/ath/ath9k/recv.c @@ -297,17 +297,19 @@ static void ath_edma_start_recv(struct ath_softc *sc) ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP, sc->rx.rx_edma[ATH9K_RX_QUEUE_LP].rx_fifo_hwsize); + spin_unlock_bh(&sc->rx.rxbuflock); + ath_opmode_init(sc); ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); - - spin_unlock_bh(&sc->rx.rxbuflock); } static void ath_edma_stop_recv(struct ath_softc *sc) { + spin_lock_bh(&sc->rx.rxbuflock); ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP); ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP); + spin_unlock_bh(&sc->rx.rxbuflock); } int ath_rx_init(struct ath_softc *sc, int nbufs) @@ -317,7 +319,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) struct ath_buf *bf; int error = 0; - spin_lock_init(&sc->rx.pcu_lock); + spin_lock_init(&sc->rx.rxflushlock); sc->sc_flags &= ~SC_OP_RXFLUSH; spin_lock_init(&sc->rx.rxbuflock); @@ -504,11 +506,10 @@ int ath_startrecv(struct ath_softc *sc) ath9k_hw_rxena(ah); start_recv: + spin_unlock_bh(&sc->rx.rxbuflock); ath_opmode_init(sc); ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); - spin_unlock_bh(&sc->rx.rxbuflock); - return 0; } @@ -517,7 +518,6 @@ bool ath_stoprecv(struct ath_softc *sc) struct ath_hw *ah = sc->sc_ah; bool stopped; - spin_lock_bh(&sc->rx.rxbuflock); ath9k_hw_stoppcurecv(ah); ath9k_hw_setrxfilter(ah, 0); stopped = ath9k_hw_stopdmarecv(ah); @@ -526,18 +526,19 @@ bool ath_stoprecv(struct ath_softc *sc) ath_edma_stop_recv(sc); else sc->rx.rxlink = NULL; - spin_unlock_bh(&sc->rx.rxbuflock); return stopped; } void ath_flushrecv(struct ath_softc *sc) { + spin_lock_bh(&sc->rx.rxflushlock); sc->sc_flags |= SC_OP_RXFLUSH; if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) ath_rx_tasklet(sc, 1, true); ath_rx_tasklet(sc, 1, false); sc->sc_flags &= ~SC_OP_RXFLUSH; + spin_unlock_bh(&sc->rx.rxflushlock); } static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c index f2ade2402ce2..30ef2dfc1ed2 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c @@ -1089,6 +1089,15 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) txq->axq_tx_inprogress = false; spin_unlock_bh(&txq->axq_lock); + /* flush any pending frames if aggregation is enabled */ + if (sc->sc_flags & SC_OP_TXAGGR) { + if (!retry_tx) { + spin_lock_bh(&txq->axq_lock); + ath_txq_drain_pending_buffers(sc, txq); + spin_unlock_bh(&txq->axq_lock); + } + } + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { spin_lock_bh(&txq->axq_lock); while (!list_empty(&txq->txq_fifo_pending)) { @@ -1109,15 +1118,6 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) } spin_unlock_bh(&txq->axq_lock); } - - /* flush any pending frames if aggregation is enabled */ - if (sc->sc_flags & SC_OP_TXAGGR) { - if (!retry_tx) { - spin_lock_bh(&txq->axq_lock); - ath_txq_drain_pending_buffers(sc, txq); - spin_unlock_bh(&txq->axq_lock); - } - } } void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) diff --git a/trunk/drivers/net/wireless/b43/sdio.c b/trunk/drivers/net/wireless/b43/sdio.c index 9a55338d957f..45933cf8e8c2 100644 --- a/trunk/drivers/net/wireless/b43/sdio.c +++ b/trunk/drivers/net/wireless/b43/sdio.c @@ -175,9 +175,7 @@ static void b43_sdio_remove(struct sdio_func *func) struct b43_sdio *sdio = sdio_get_drvdata(func); ssb_bus_unregister(&sdio->ssb); - sdio_claim_host(func); sdio_disable_func(func); - sdio_release_host(func); kfree(sdio); sdio_set_drvdata(func, NULL); } diff --git a/trunk/drivers/net/wireless/libertas/if_sdio.c b/trunk/drivers/net/wireless/libertas/if_sdio.c index e5685dc317a8..296fd00a5129 100644 --- a/trunk/drivers/net/wireless/libertas/if_sdio.c +++ b/trunk/drivers/net/wireless/libertas/if_sdio.c @@ -684,40 +684,18 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card) lbs_deb_enter(LBS_DEB_SDIO); - /* - * Disable interrupts - */ - sdio_claim_host(card->func); - sdio_writeb(card->func, 0x00, IF_SDIO_H_INT_MASK, &ret); - sdio_release_host(card->func); - sdio_claim_host(card->func); scratch = if_sdio_read_scratch(card, &ret); sdio_release_host(card->func); - lbs_deb_sdio("firmware status = %#x\n", scratch); - lbs_deb_sdio("scratch ret = %d\n", ret); - if (ret) goto out; + lbs_deb_sdio("firmware status = %#x\n", scratch); - /* - * The manual clearly describes that FEDC is the right code to use - * to detect firmware presence, but for SD8686 it is not that simple. - * Scratch is also used to store the RX packet length, so we lose - * the FEDC value early on. So we use a non-zero check in order - * to validate firmware presence. - * Additionally, the SD8686 in the Gumstix always has the high scratch - * bit set, even when the firmware is not loaded. So we have to - * exclude that from the test. - */ if (scratch == IF_SDIO_FIRMWARE_OK) { lbs_deb_sdio("firmware already loaded\n"); goto success; - } else if ((card->model == MODEL_8686) && (scratch & 0x7fff)) { - lbs_deb_sdio("firmware may be running\n"); - goto success; } ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name, @@ -731,14 +709,10 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card) if (ret) goto out; - lbs_deb_sdio("Helper firmware loaded\n"); - ret = if_sdio_prog_real(card, mainfw); if (ret) goto out; - lbs_deb_sdio("Firmware loaded\n"); - success: sdio_claim_host(card->func); sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE); @@ -1068,6 +1042,8 @@ static int if_sdio_probe(struct sdio_func *func, priv->exit_deep_sleep = if_sdio_exit_deep_sleep; priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup; + priv->fw_ready = 1; + sdio_claim_host(func); /* @@ -1088,8 +1064,6 @@ static int if_sdio_probe(struct sdio_func *func, if (ret) goto reclaim; - priv->fw_ready = 1; - /* * FUNC_INIT is required for SD8688 WLAN/BT multiple functions */ diff --git a/trunk/drivers/oprofile/oprofilefs.c b/trunk/drivers/oprofile/oprofilefs.c index e9ff6f7770be..449de59bf35b 100644 --- a/trunk/drivers/oprofile/oprofilefs.c +++ b/trunk/drivers/oprofile/oprofilefs.c @@ -259,17 +259,17 @@ static int oprofilefs_fill_super(struct super_block *sb, void *data, int silent) } -static struct dentry *oprofilefs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int oprofilefs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_single(fs_type, flags, data, oprofilefs_fill_super); + return get_sb_single(fs_type, flags, data, oprofilefs_fill_super, mnt); } static struct file_system_type oprofilefs_type = { .owner = THIS_MODULE, .name = "oprofilefs", - .mount = oprofilefs_mount, + .get_sb = oprofilefs_get_sb, .kill_sb = kill_litter_super, }; diff --git a/trunk/drivers/s390/block/dasd_eckd.c b/trunk/drivers/s390/block/dasd_eckd.c index bf61274af3bb..50cf96389d2c 100644 --- a/trunk/drivers/s390/block/dasd_eckd.c +++ b/trunk/drivers/s390/block/dasd_eckd.c @@ -2801,73 +2801,6 @@ dasd_eckd_steal_lock(struct dasd_device *device) return rc; } -/* - * SNID - Sense Path Group ID - * This ioctl may be used in situations where I/O is stalled due to - * a reserve, so if the normal dasd_smalloc_request fails, we use the - * preallocated dasd_reserve_req. - */ -static int dasd_eckd_snid(struct dasd_device *device, - void __user *argp) -{ - struct dasd_ccw_req *cqr; - int rc; - struct ccw1 *ccw; - int useglobal; - struct dasd_snid_ioctl_data usrparm; - - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - - if (copy_from_user(&usrparm, argp, sizeof(usrparm))) - return -EFAULT; - - useglobal = 0; - cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, - sizeof(struct dasd_snid_data), device); - if (IS_ERR(cqr)) { - mutex_lock(&dasd_reserve_mutex); - useglobal = 1; - cqr = &dasd_reserve_req->cqr; - memset(cqr, 0, sizeof(*cqr)); - memset(&dasd_reserve_req->ccw, 0, - sizeof(dasd_reserve_req->ccw)); - cqr->cpaddr = &dasd_reserve_req->ccw; - cqr->data = &dasd_reserve_req->data; - cqr->magic = DASD_ECKD_MAGIC; - } - ccw = cqr->cpaddr; - ccw->cmd_code = DASD_ECKD_CCW_SNID; - ccw->flags |= CCW_FLAG_SLI; - ccw->count = 12; - ccw->cda = (__u32)(addr_t) cqr->data; - cqr->startdev = device; - cqr->memdev = device; - clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); - set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); - cqr->retries = 5; - cqr->expires = 10 * HZ; - cqr->buildclk = get_clock(); - cqr->status = DASD_CQR_FILLED; - cqr->lpm = usrparm.path_mask; - - rc = dasd_sleep_on_immediatly(cqr); - /* verify that I/O processing didn't modify the path mask */ - if (!rc && usrparm.path_mask && (cqr->lpm != usrparm.path_mask)) - rc = -EIO; - if (!rc) { - usrparm.data = *((struct dasd_snid_data *)cqr->data); - if (copy_to_user(argp, &usrparm, sizeof(usrparm))) - rc = -EFAULT; - } - - if (useglobal) - mutex_unlock(&dasd_reserve_mutex); - else - dasd_sfree_request(cqr, cqr->memdev); - return rc; -} - /* * Read performance statistics */ @@ -3103,8 +3036,6 @@ dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp) return dasd_eckd_reserve(device); case BIODASDSLCK: return dasd_eckd_steal_lock(device); - case BIODASDSNID: - return dasd_eckd_snid(device, argp); case BIODASDSYMMIO: return dasd_symm_io(device, argp); default: diff --git a/trunk/drivers/s390/block/dasd_eckd.h b/trunk/drivers/s390/block/dasd_eckd.h index 12097c24f2f5..0eb49655a6cd 100644 --- a/trunk/drivers/s390/block/dasd_eckd.h +++ b/trunk/drivers/s390/block/dasd_eckd.h @@ -27,7 +27,6 @@ #define DASD_ECKD_CCW_WRITE_CKD 0x1d #define DASD_ECKD_CCW_READ_CKD 0x1e #define DASD_ECKD_CCW_PSF 0x27 -#define DASD_ECKD_CCW_SNID 0x34 #define DASD_ECKD_CCW_RSSD 0x3e #define DASD_ECKD_CCW_LOCATE_RECORD 0x47 #define DASD_ECKD_CCW_SNSS 0x54 diff --git a/trunk/drivers/s390/char/tape_core.c b/trunk/drivers/s390/char/tape_core.c index 6c408670e08d..29c2d73d719d 100644 --- a/trunk/drivers/s390/char/tape_core.c +++ b/trunk/drivers/s390/char/tape_core.c @@ -1077,14 +1077,15 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) /* FIXME: What to do with the request? */ switch (PTR_ERR(irb)) { case -ETIMEDOUT: - DBF_LH(1, "(%08x): Request timed out\n", - device->cdev_id); + DBF_LH(1, "(%s): Request timed out\n", + dev_name(&cdev->dev)); case -EIO: __tape_end_request(device, request, -EIO); break; default: - DBF_LH(1, "(%08x): Unexpected i/o error %li\n", - device->cdev_id, PTR_ERR(irb)); + DBF_LH(1, "(%s): Unexpected i/o error %li\n", + dev_name(&cdev->dev), + PTR_ERR(irb)); } return; } diff --git a/trunk/drivers/s390/char/tape_std.c b/trunk/drivers/s390/char/tape_std.c index 3c3f342149ec..03f07e5dd6e9 100644 --- a/trunk/drivers/s390/char/tape_std.c +++ b/trunk/drivers/s390/char/tape_std.c @@ -47,8 +47,8 @@ tape_std_assign_timeout(unsigned long data) device->cdev_id); rc = tape_cancel_io(device, request); if(rc) - DBF_EVENT(3, "(%08x): Assign timeout: Cancel failed with rc = " - "%i\n", device->cdev_id, rc); + DBF_EVENT(3, "(%s): Assign timeout: Cancel failed with rc = %i\n", + dev_name(&device->cdev->dev), rc); } int diff --git a/trunk/drivers/staging/Kconfig b/trunk/drivers/staging/Kconfig index 5eafdf435550..f9c9c8a397db 100644 --- a/trunk/drivers/staging/Kconfig +++ b/trunk/drivers/staging/Kconfig @@ -87,6 +87,8 @@ source "drivers/staging/rtl8712/Kconfig" source "drivers/staging/frontier/Kconfig" +source "drivers/staging/dream/Kconfig" + source "drivers/staging/pohmelfs/Kconfig" source "drivers/staging/autofs/Kconfig" diff --git a/trunk/drivers/staging/Makefile b/trunk/drivers/staging/Makefile index a97a955c094b..a85074f8321b 100644 --- a/trunk/drivers/staging/Makefile +++ b/trunk/drivers/staging/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_R8712U) += rtl8712/ obj-$(CONFIG_SPECTRA) += spectra/ obj-$(CONFIG_TRANZPORT) += frontier/ +obj-$(CONFIG_DREAM) += dream/ obj-$(CONFIG_POHMELFS) += pohmelfs/ obj-$(CONFIG_AUTOFS_FS) += autofs/ obj-$(CONFIG_IDE_PHISON) += phison/ diff --git a/trunk/drivers/staging/autofs/init.c b/trunk/drivers/staging/autofs/init.c index 5e4b372ea663..765c72f42976 100644 --- a/trunk/drivers/staging/autofs/init.c +++ b/trunk/drivers/staging/autofs/init.c @@ -14,16 +14,16 @@ #include #include "autofs_i.h" -static struct dentry *autofs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int autofs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_nodev(fs_type, flags, data, autofs_fill_super); + return get_sb_nodev(fs_type, flags, data, autofs_fill_super, mnt); } static struct file_system_type autofs_fs_type = { .owner = THIS_MODULE, .name = "autofs", - .mount = autofs_mount, + .get_sb = autofs_get_sb, .kill_sb = autofs_kill_sb, }; diff --git a/trunk/drivers/staging/dream/Kconfig b/trunk/drivers/staging/dream/Kconfig new file mode 100644 index 000000000000..0c30b19a5a7c --- /dev/null +++ b/trunk/drivers/staging/dream/Kconfig @@ -0,0 +1,13 @@ +config DREAM + tristate "HTC Dream support" + depends on MACH_TROUT + +if DREAM + +source "drivers/staging/dream/camera/Kconfig" + +config INPUT_GPIO + tristate "GPIO driver support" + help + Say Y here if you want to support gpio based keys, wheels etc... +endif diff --git a/trunk/drivers/staging/dream/Makefile b/trunk/drivers/staging/dream/Makefile new file mode 100644 index 000000000000..87de1a57f237 --- /dev/null +++ b/trunk/drivers/staging/dream/Makefile @@ -0,0 +1,5 @@ +ccflags-y:=-Idrivers/staging/dream/include +obj-$(CONFIG_MSM_ADSP) += qdsp5/ +obj-$(CONFIG_MSM_CAMERA) += camera/ +obj-$(CONFIG_INPUT_GPIO) += gpio_axis.o gpio_event.o gpio_input.o gpio_matrix.o gpio_output.o + diff --git a/trunk/drivers/staging/dream/TODO b/trunk/drivers/staging/dream/TODO new file mode 100644 index 000000000000..dcd3ba808655 --- /dev/null +++ b/trunk/drivers/staging/dream/TODO @@ -0,0 +1,13 @@ + +* camera driver uses old V4L API + +* coding style in some places is lacking + +* gpio_input.c has some features matrix_keypad lacks. They should be +merged to gpio_input, with gpio_input.c removed + +* pmem provides interface for userspace. Needs to be reviewed at least. + +* it is probably possible to simplify touchscreen driver using threaded_irq's. + +* touchscreen driver should be switched to oficial multitouch API diff --git a/trunk/drivers/staging/dream/camera/Kconfig b/trunk/drivers/staging/dream/camera/Kconfig new file mode 100644 index 000000000000..bfb6d241d807 --- /dev/null +++ b/trunk/drivers/staging/dream/camera/Kconfig @@ -0,0 +1,46 @@ +comment "Qualcomm MSM Camera And Video" + +menuconfig MSM_CAMERA + bool "Qualcomm MSM camera and video capture support" + depends on ARCH_MSM && VIDEO_V4L2_COMMON + help + Say Y here to enable selecting the video adapters for + Qualcomm msm camera and video encoding + +config MSM_CAMERA_DEBUG + bool "Qualcomm MSM camera debugging with printk" + depends on MSM_CAMERA + help + Enable printk() debug for msm camera + +config MSM_CAMERA_FLASH + bool "Qualcomm MSM camera flash support" + depends on MSM_CAMERA && BROKEN + ---help--- + Enable support for LED flash for msm camera + + +comment "Camera Sensor Selection" +config MT9T013 + bool "Sensor mt9t013 (BAYER 3M)" + depends on MSM_CAMERA + ---help--- + MICRON 3M Bayer Sensor with AutoFocus + +config MT9D112 + bool "Sensor mt9d112 (YUV 2M)" + depends on MSM_CAMERA + ---help--- + MICRON 2M YUV Sensor + +config MT9P012 + bool "Sensor mt9p012 (BAYER 5M)" + depends on MSM_CAMERA + ---help--- + MICRON 5M Bayer Sensor with Autofocus + +config S5K3E2FX + bool "Sensor s5k3e2fx (Samsung 5M)" + depends on MSM_CAMERA + ---help--- + Samsung 5M with Autofocus diff --git a/trunk/drivers/staging/dream/camera/Makefile b/trunk/drivers/staging/dream/camera/Makefile new file mode 100644 index 000000000000..03711dc6f482 --- /dev/null +++ b/trunk/drivers/staging/dream/camera/Makefile @@ -0,0 +1,8 @@ +ccflags-y:=-Idrivers/staging/dream/include +obj-$(CONFIG_MT9T013) += mt9t013.o mt9t013_reg.o +obj-$(CONFIG_MT9D112) += mt9d112.o mt9d112_reg.o +obj-$(CONFIG_MT9P012) += mt9p012_fox.o mt9p012_reg.o +obj-$(CONFIG_MSM_CAMERA) += msm_camera.o msm_v4l2.o +obj-$(CONFIG_S5K3E2FX) += s5k3e2fx.o +obj-$(CONFIG_ARCH_MSM) += msm_vfe7x.o msm_io7x.o +obj-$(CONFIG_ARCH_QSD) += msm_vfe8x.o msm_vfe8x_proc.o msm_io8x.o diff --git a/trunk/drivers/staging/dream/camera/msm_camera.c b/trunk/drivers/staging/dream/camera/msm_camera.c new file mode 100644 index 000000000000..de4ab61efd4b --- /dev/null +++ b/trunk/drivers/staging/dream/camera/msm_camera.c @@ -0,0 +1,2181 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ + +/* FIXME: most allocations need not be GFP_ATOMIC */ +/* FIXME: management of mutexes */ +/* FIXME: msm_pmem_region_lookup return values */ +/* FIXME: way too many copy to/from user */ +/* FIXME: does region->active mean free */ +/* FIXME: check limits on command lenghts passed from userspace */ +/* FIXME: __msm_release: which queues should we flush when opencnt != 0 */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define MSM_MAX_CAMERA_SENSORS 5 + +#define ERR_USER_COPY(to) pr_err("%s(%d): copy %s user\n", \ + __func__, __LINE__, ((to) ? "to" : "from")) +#define ERR_COPY_FROM_USER() ERR_USER_COPY(0) +#define ERR_COPY_TO_USER() ERR_USER_COPY(1) + +static struct class *msm_class; +static dev_t msm_devno; +static LIST_HEAD(msm_sensors); + +#define __CONTAINS(r, v, l, field) ({ \ + typeof(r) __r = r; \ + typeof(v) __v = v; \ + typeof(v) __e = __v + l; \ + int res = __v >= __r->field && \ + __e <= __r->field + __r->len; \ + res; \ +}) + +#define CONTAINS(r1, r2, field) ({ \ + typeof(r2) __r2 = r2; \ + __CONTAINS(r1, __r2->field, __r2->len, field); \ +}) + +#define IN_RANGE(r, v, field) ({ \ + typeof(r) __r = r; \ + typeof(v) __vv = v; \ + int res = ((__vv >= __r->field) && \ + (__vv < (__r->field + __r->len))); \ + res; \ +}) + +#define OVERLAPS(r1, r2, field) ({ \ + typeof(r1) __r1 = r1; \ + typeof(r2) __r2 = r2; \ + typeof(__r2->field) __v = __r2->field; \ + typeof(__v) __e = __v + __r2->len - 1; \ + int res = (IN_RANGE(__r1, __v, field) || \ + IN_RANGE(__r1, __e, field)); \ + res; \ +}) + +#define MSM_DRAIN_QUEUE_NOSYNC(sync, name) do { \ + struct msm_queue_cmd *qcmd = NULL; \ + CDBG("%s: draining queue "#name"\n", __func__); \ + while (!list_empty(&(sync)->name)) { \ + qcmd = list_first_entry(&(sync)->name, \ + struct msm_queue_cmd, list); \ + list_del_init(&qcmd->list); \ + kfree(qcmd); \ + }; \ +} while (0) + +#define MSM_DRAIN_QUEUE(sync, name) do { \ + unsigned long flags; \ + spin_lock_irqsave(&(sync)->name##_lock, flags); \ + MSM_DRAIN_QUEUE_NOSYNC(sync, name); \ + spin_unlock_irqrestore(&(sync)->name##_lock, flags); \ +} while (0) + +static int check_overlap(struct hlist_head *ptype, + unsigned long paddr, + unsigned long len) +{ + struct msm_pmem_region *region; + struct msm_pmem_region t = { .paddr = paddr, .len = len }; + struct hlist_node *node; + + hlist_for_each_entry(region, node, ptype, list) { + if (CONTAINS(region, &t, paddr) || + CONTAINS(&t, region, paddr) || + OVERLAPS(region, &t, paddr)) { + printk(KERN_ERR + " region (PHYS %p len %ld)" + " clashes with registered region" + " (paddr %p len %ld)\n", + (void *)t.paddr, t.len, + (void *)region->paddr, region->len); + return -1; + } + } + + return 0; +} + +static int msm_pmem_table_add(struct hlist_head *ptype, + struct msm_pmem_info *info) +{ + struct file *file; + unsigned long paddr; + unsigned long vstart; + unsigned long len; + int rc; + struct msm_pmem_region *region; + + rc = get_pmem_file(info->fd, &paddr, &vstart, &len, &file); + if (rc < 0) { + pr_err("msm_pmem_table_add: get_pmem_file fd %d error %d\n", + info->fd, rc); + return rc; + } + + if (check_overlap(ptype, paddr, len) < 0) + return -EINVAL; + + CDBG("%s: type = %d, paddr = 0x%lx, vaddr = 0x%lx\n", + __func__, + info->type, paddr, (unsigned long)info->vaddr); + + region = kmalloc(sizeof(*region), GFP_KERNEL); + if (!region) + return -ENOMEM; + + INIT_HLIST_NODE(®ion->list); + + region->type = info->type; + region->vaddr = info->vaddr; + region->paddr = paddr; + region->len = len; + region->file = file; + region->y_off = info->y_off; + region->cbcr_off = info->cbcr_off; + region->fd = info->fd; + region->active = info->active; + + hlist_add_head(&(region->list), ptype); + + return 0; +} + +/* return of 0 means failure */ +static uint8_t msm_pmem_region_lookup(struct hlist_head *ptype, + int pmem_type, struct msm_pmem_region *reg, uint8_t maxcount) +{ + struct msm_pmem_region *region; + struct msm_pmem_region *regptr; + struct hlist_node *node, *n; + + uint8_t rc = 0; + + regptr = reg; + + hlist_for_each_entry_safe(region, node, n, ptype, list) { + if (region->type == pmem_type && region->active) { + *regptr = *region; + rc += 1; + if (rc >= maxcount) + break; + regptr++; + } + } + + return rc; +} + +static unsigned long msm_pmem_frame_ptov_lookup(struct msm_sync *sync, + unsigned long pyaddr, + unsigned long pcbcraddr, + uint32_t *yoff, uint32_t *cbcroff, int *fd) +{ + struct msm_pmem_region *region; + struct hlist_node *node, *n; + + hlist_for_each_entry_safe(region, node, n, &sync->frame, list) { + if (pyaddr == (region->paddr + region->y_off) && + pcbcraddr == (region->paddr + + region->cbcr_off) && + region->active) { + /* offset since we could pass vaddr inside + * a registerd pmem buffer + */ + *yoff = region->y_off; + *cbcroff = region->cbcr_off; + *fd = region->fd; + region->active = 0; + return (unsigned long)(region->vaddr); + } + } + + return 0; +} + +static unsigned long msm_pmem_stats_ptov_lookup(struct msm_sync *sync, + unsigned long addr, int *fd) +{ + struct msm_pmem_region *region; + struct hlist_node *node, *n; + + hlist_for_each_entry_safe(region, node, n, &sync->stats, list) { + if (addr == region->paddr && region->active) { + /* offset since we could pass vaddr inside a + * registered pmem buffer */ + *fd = region->fd; + region->active = 0; + return (unsigned long)(region->vaddr); + } + } + + return 0; +} + +static unsigned long msm_pmem_frame_vtop_lookup(struct msm_sync *sync, + unsigned long buffer, + uint32_t yoff, uint32_t cbcroff, int fd) +{ + struct msm_pmem_region *region; + struct hlist_node *node, *n; + + hlist_for_each_entry_safe(region, + node, n, &sync->frame, list) { + if (((unsigned long)(region->vaddr) == buffer) && + (region->y_off == yoff) && + (region->cbcr_off == cbcroff) && + (region->fd == fd) && + (region->active == 0)) { + + region->active = 1; + return region->paddr; + } + } + + return 0; +} + +static unsigned long msm_pmem_stats_vtop_lookup( + struct msm_sync *sync, + unsigned long buffer, + int fd) +{ + struct msm_pmem_region *region; + struct hlist_node *node, *n; + + hlist_for_each_entry_safe(region, node, n, &sync->stats, list) { + if (((unsigned long)(region->vaddr) == buffer) && + (region->fd == fd) && region->active == 0) { + region->active = 1; + return region->paddr; + } + } + + return 0; +} + +static int __msm_pmem_table_del(struct msm_sync *sync, + struct msm_pmem_info *pinfo) +{ + int rc = 0; + struct msm_pmem_region *region; + struct hlist_node *node, *n; + + switch (pinfo->type) { + case MSM_PMEM_OUTPUT1: + case MSM_PMEM_OUTPUT2: + case MSM_PMEM_THUMBAIL: + case MSM_PMEM_MAINIMG: + case MSM_PMEM_RAW_MAINIMG: + hlist_for_each_entry_safe(region, node, n, + &sync->frame, list) { + + if (pinfo->type == region->type && + pinfo->vaddr == region->vaddr && + pinfo->fd == region->fd) { + hlist_del(node); + put_pmem_file(region->file); + kfree(region); + } + } + break; + + case MSM_PMEM_AEC_AWB: + case MSM_PMEM_AF: + hlist_for_each_entry_safe(region, node, n, + &sync->stats, list) { + + if (pinfo->type == region->type && + pinfo->vaddr == region->vaddr && + pinfo->fd == region->fd) { + hlist_del(node); + put_pmem_file(region->file); + kfree(region); + } + } + break; + + default: + rc = -EINVAL; + break; + } + + return rc; +} + +static int msm_pmem_table_del(struct msm_sync *sync, void __user *arg) +{ + struct msm_pmem_info info; + + if (copy_from_user(&info, arg, sizeof(info))) { + ERR_COPY_FROM_USER(); + return -EFAULT; + } + + return __msm_pmem_table_del(sync, &info); +} + +static int __msm_get_frame(struct msm_sync *sync, + struct msm_frame *frame) +{ + unsigned long flags; + int rc = 0; + + struct msm_queue_cmd *qcmd = NULL; + struct msm_vfe_phy_info *pphy; + + spin_lock_irqsave(&sync->prev_frame_q_lock, flags); + if (!list_empty(&sync->prev_frame_q)) { + qcmd = list_first_entry(&sync->prev_frame_q, + struct msm_queue_cmd, list); + list_del_init(&qcmd->list); + } + spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags); + + if (!qcmd) { + pr_err("%s: no preview frame.\n", __func__); + return -EAGAIN; + } + + pphy = (struct msm_vfe_phy_info *)(qcmd->command); + + frame->buffer = + msm_pmem_frame_ptov_lookup(sync, + pphy->y_phy, + pphy->cbcr_phy, &(frame->y_off), + &(frame->cbcr_off), &(frame->fd)); + if (!frame->buffer) { + pr_err("%s: cannot get frame, invalid lookup address " + "y=%x cbcr=%x offset=%d\n", + __func__, + pphy->y_phy, + pphy->cbcr_phy, + frame->y_off); + rc = -EINVAL; + } + + CDBG("__msm_get_frame: y=0x%x, cbcr=0x%x, qcmd=0x%x, virt_addr=0x%x\n", + pphy->y_phy, pphy->cbcr_phy, (int) qcmd, (int) frame->buffer); + + kfree(qcmd); + return rc; +} + +static int msm_get_frame(struct msm_sync *sync, void __user *arg) +{ + int rc = 0; + struct msm_frame frame; + + if (copy_from_user(&frame, + arg, + sizeof(struct msm_frame))) { + ERR_COPY_FROM_USER(); + return -EFAULT; + } + + rc = __msm_get_frame(sync, &frame); + if (rc < 0) + return rc; + + if (sync->croplen) { + if (frame.croplen > sync->croplen) { + pr_err("msm_get_frame: invalid frame croplen %d\n", + frame.croplen); + return -EINVAL; + } + + if (copy_to_user((void *)frame.cropinfo, + sync->cropinfo, + sync->croplen)) { + ERR_COPY_TO_USER(); + return -EFAULT; + } + } + + if (copy_to_user((void *)arg, + &frame, sizeof(struct msm_frame))) { + ERR_COPY_TO_USER(); + rc = -EFAULT; + } + + CDBG("Got frame!!!\n"); + + return rc; +} + +static int msm_enable_vfe(struct msm_sync *sync, void __user *arg) +{ + int rc = -EIO; + struct camera_enable_cmd cfg; + + if (copy_from_user(&cfg, + arg, + sizeof(struct camera_enable_cmd))) { + ERR_COPY_FROM_USER(); + return -EFAULT; + } + + if (sync->vfefn.vfe_enable) + rc = sync->vfefn.vfe_enable(&cfg); + + CDBG("msm_enable_vfe: returned rc = %d\n", rc); + return rc; +} + +static int msm_disable_vfe(struct msm_sync *sync, void __user *arg) +{ + int rc = -EIO; + struct camera_enable_cmd cfg; + + if (copy_from_user(&cfg, + arg, + sizeof(struct camera_enable_cmd))) { + ERR_COPY_FROM_USER(); + return -EFAULT; + } + + if (sync->vfefn.vfe_disable) + rc = sync->vfefn.vfe_disable(&cfg, NULL); + + CDBG("msm_disable_vfe: returned rc = %d\n", rc); + return rc; +} + +static struct msm_queue_cmd *__msm_control(struct msm_sync *sync, + struct msm_control_device_queue *queue, + struct msm_queue_cmd *qcmd, + int timeout) +{ + unsigned long flags; + int rc; + + spin_lock_irqsave(&sync->msg_event_q_lock, flags); + list_add_tail(&qcmd->list, &sync->msg_event_q); + /* wake up config thread */ + wake_up(&sync->msg_event_wait); + spin_unlock_irqrestore(&sync->msg_event_q_lock, flags); + + if (!queue) + return NULL; + + /* wait for config status */ + rc = wait_event_interruptible_timeout( + queue->ctrl_status_wait, + !list_empty_careful(&queue->ctrl_status_q), + timeout); + if (list_empty_careful(&queue->ctrl_status_q)) { + if (!rc) + rc = -ETIMEDOUT; + if (rc < 0) { + pr_err("msm_control: wait_event error %d\n", rc); +#if 0 + /* This is a bit scary. If we time out too early, we + * will free qcmd at the end of this function, and the + * dsp may do the same when it does respond, so we + * remove the message from the source queue. + */ + pr_err("%s: error waiting for ctrl_status_q: %d\n", + __func__, rc); + spin_lock_irqsave(&sync->msg_event_q_lock, flags); + list_del_init(&qcmd->list); + spin_unlock_irqrestore(&sync->msg_event_q_lock, flags); +#endif + return ERR_PTR(rc); + } + } + + /* control command status is ready */ + spin_lock_irqsave(&queue->ctrl_status_q_lock, flags); + BUG_ON(list_empty(&queue->ctrl_status_q)); + qcmd = list_first_entry(&queue->ctrl_status_q, + struct msm_queue_cmd, list); + list_del_init(&qcmd->list); + spin_unlock_irqrestore(&queue->ctrl_status_q_lock, flags); + + return qcmd; +} + +static int msm_control(struct msm_control_device *ctrl_pmsm, + int block, + void __user *arg) +{ + int rc = 0; + + struct msm_sync *sync = ctrl_pmsm->pmsm->sync; + struct msm_ctrl_cmd udata, *ctrlcmd; + struct msm_queue_cmd *qcmd = NULL, *qcmd_temp; + + if (copy_from_user(&udata, arg, sizeof(struct msm_ctrl_cmd))) { + ERR_COPY_FROM_USER(); + rc = -EFAULT; + goto end; + } + + qcmd = kmalloc(sizeof(struct msm_queue_cmd) + + sizeof(struct msm_ctrl_cmd) + udata.length, + GFP_KERNEL); + if (!qcmd) { + pr_err("msm_control: cannot allocate buffer\n"); + rc = -ENOMEM; + goto end; + } + + qcmd->type = MSM_CAM_Q_CTRL; + qcmd->command = ctrlcmd = (struct msm_ctrl_cmd *)(qcmd + 1); + *ctrlcmd = udata; + ctrlcmd->value = ctrlcmd + 1; + + if (udata.length) { + if (copy_from_user(ctrlcmd->value, + udata.value, udata.length)) { + ERR_COPY_FROM_USER(); + rc = -EFAULT; + goto end; + } + } + + if (!block) { + /* qcmd will be set to NULL */ + qcmd = __msm_control(sync, NULL, qcmd, 0); + goto end; + } + + qcmd_temp = __msm_control(sync, + &ctrl_pmsm->ctrl_q, + qcmd, MAX_SCHEDULE_TIMEOUT); + + if (IS_ERR(qcmd_temp)) { + rc = PTR_ERR(qcmd_temp); + goto end; + } + qcmd = qcmd_temp; + + if (qcmd->command) { + void __user *to = udata.value; + udata = *(struct msm_ctrl_cmd *)qcmd->command; + if (udata.length > 0) { + if (copy_to_user(to, + udata.value, + udata.length)) { + ERR_COPY_TO_USER(); + rc = -EFAULT; + goto end; + } + } + udata.value = to; + + if (copy_to_user((void *)arg, &udata, + sizeof(struct msm_ctrl_cmd))) { + ERR_COPY_TO_USER(); + rc = -EFAULT; + goto end; + } + } + +end: + /* Note: if we get here as a result of an error, we will free the + * qcmd that we kmalloc() in this function. When we come here as + * a result of a successful completion, we are freeing the qcmd that + * we dequeued from queue->ctrl_status_q. + */ + kfree(qcmd); + + CDBG("msm_control: end rc = %d\n", rc); + return rc; +} + +static int msm_get_stats(struct msm_sync *sync, void __user *arg) +{ + unsigned long flags; + int timeout; + int rc = 0; + + struct msm_stats_event_ctrl se; + + struct msm_queue_cmd *qcmd = NULL; + struct msm_ctrl_cmd *ctrl = NULL; + struct msm_vfe_resp *data = NULL; + struct msm_stats_buf stats; + + if (copy_from_user(&se, arg, + sizeof(struct msm_stats_event_ctrl))) { + ERR_COPY_FROM_USER(); + return -EFAULT; + } + + timeout = (int)se.timeout_ms; + + CDBG("msm_get_stats timeout %d\n", timeout); + rc = wait_event_interruptible_timeout( + sync->msg_event_wait, + !list_empty_careful(&sync->msg_event_q), + msecs_to_jiffies(timeout)); + if (list_empty_careful(&sync->msg_event_q)) { + if (rc == 0) + rc = -ETIMEDOUT; + if (rc < 0) { + pr_err("msm_get_stats error %d\n", rc); + return rc; + } + } + CDBG("msm_get_stats returned from wait: %d\n", rc); + + spin_lock_irqsave(&sync->msg_event_q_lock, flags); + BUG_ON(list_empty(&sync->msg_event_q)); + qcmd = list_first_entry(&sync->msg_event_q, + struct msm_queue_cmd, list); + list_del_init(&qcmd->list); + spin_unlock_irqrestore(&sync->msg_event_q_lock, flags); + + CDBG("=== received from DSP === %d\n", qcmd->type); + + switch (qcmd->type) { + case MSM_CAM_Q_VFE_EVT: + case MSM_CAM_Q_VFE_MSG: + data = (struct msm_vfe_resp *)(qcmd->command); + + /* adsp event and message */ + se.resptype = MSM_CAM_RESP_STAT_EVT_MSG; + + /* 0 - msg from aDSP, 1 - event from mARM */ + se.stats_event.type = data->evt_msg.type; + se.stats_event.msg_id = data->evt_msg.msg_id; + se.stats_event.len = data->evt_msg.len; + + CDBG("msm_get_stats, qcmd->type = %d\n", qcmd->type); + CDBG("length = %d\n", se.stats_event.len); + CDBG("msg_id = %d\n", se.stats_event.msg_id); + + if ((data->type == VFE_MSG_STATS_AF) || + (data->type == VFE_MSG_STATS_WE)) { + + stats.buffer = + msm_pmem_stats_ptov_lookup(sync, + data->phy.sbuf_phy, + &(stats.fd)); + if (!stats.buffer) { + pr_err("%s: msm_pmem_stats_ptov_lookup error\n", + __func__); + rc = -EINVAL; + goto failure; + } + + if (copy_to_user((void *)(se.stats_event.data), + &stats, + sizeof(struct msm_stats_buf))) { + ERR_COPY_TO_USER(); + rc = -EFAULT; + goto failure; + } + } else if ((data->evt_msg.len > 0) && + (data->type == VFE_MSG_GENERAL)) { + if (copy_to_user((void *)(se.stats_event.data), + data->evt_msg.data, + data->evt_msg.len)) { + ERR_COPY_TO_USER(); + rc = -EFAULT; + } + } else if (data->type == VFE_MSG_OUTPUT1 || + data->type == VFE_MSG_OUTPUT2) { + if (copy_to_user((void *)(se.stats_event.data), + data->extdata, + data->extlen)) { + ERR_COPY_TO_USER(); + rc = -EFAULT; + } + } else if (data->type == VFE_MSG_SNAPSHOT && sync->pict_pp) { + struct msm_postproc buf; + struct msm_pmem_region region; + buf.fmnum = msm_pmem_region_lookup(&sync->frame, + MSM_PMEM_MAINIMG, + ®ion, 1); + if (buf.fmnum == 1) { + buf.fmain.buffer = (unsigned long)region.vaddr; + buf.fmain.y_off = region.y_off; + buf.fmain.cbcr_off = region.cbcr_off; + buf.fmain.fd = region.fd; + } else { + buf.fmnum = msm_pmem_region_lookup(&sync->frame, + MSM_PMEM_RAW_MAINIMG, + ®ion, 1); + if (buf.fmnum == 1) { + buf.fmain.path = MSM_FRAME_PREV_2; + buf.fmain.buffer = + (unsigned long)region.vaddr; + buf.fmain.fd = region.fd; + } else { + pr_err("%s: pmem lookup failed\n", + __func__); + rc = -EINVAL; + } + } + + if (copy_to_user((void *)(se.stats_event.data), &buf, + sizeof(buf))) { + ERR_COPY_TO_USER(); + rc = -EFAULT; + goto failure; + } + CDBG("snapshot copy_to_user!\n"); + } + break; + + case MSM_CAM_Q_CTRL: + /* control command from control thread */ + ctrl = (struct msm_ctrl_cmd *)(qcmd->command); + + CDBG("msm_get_stats, qcmd->type = %d\n", qcmd->type); + CDBG("length = %d\n", ctrl->length); + + if (ctrl->length > 0) { + if (copy_to_user((void *)(se.ctrl_cmd.value), + ctrl->value, + ctrl->length)) { + ERR_COPY_TO_USER(); + rc = -EFAULT; + goto failure; + } + } + + se.resptype = MSM_CAM_RESP_CTRL; + + /* what to control */ + se.ctrl_cmd.type = ctrl->type; + se.ctrl_cmd.length = ctrl->length; + se.ctrl_cmd.resp_fd = ctrl->resp_fd; + break; + + case MSM_CAM_Q_V4L2_REQ: + /* control command from v4l2 client */ + ctrl = (struct msm_ctrl_cmd *)(qcmd->command); + + CDBG("msm_get_stats, qcmd->type = %d\n", qcmd->type); + CDBG("length = %d\n", ctrl->length); + + if (ctrl->length > 0) { + if (copy_to_user((void *)(se.ctrl_cmd.value), + ctrl->value, ctrl->length)) { + ERR_COPY_TO_USER(); + rc = -EFAULT; + goto failure; + } + } + + /* 2 tells config thread this is v4l2 request */ + se.resptype = MSM_CAM_RESP_V4L2; + + /* what to control */ + se.ctrl_cmd.type = ctrl->type; + se.ctrl_cmd.length = ctrl->length; + break; + + default: + rc = -EFAULT; + goto failure; + } /* switch qcmd->type */ + + if (copy_to_user((void *)arg, &se, sizeof(se))) { + ERR_COPY_TO_USER(); + rc = -EFAULT; + } + +failure: + kfree(qcmd); + + CDBG("msm_get_stats: %d\n", rc); + return rc; +} + +static int msm_ctrl_cmd_done(struct msm_control_device *ctrl_pmsm, + void __user *arg) +{ + unsigned long flags; + int rc = 0; + + struct msm_ctrl_cmd udata, *ctrlcmd; + struct msm_queue_cmd *qcmd = NULL; + + if (copy_from_user(&udata, arg, sizeof(struct msm_ctrl_cmd))) { + ERR_COPY_FROM_USER(); + rc = -EFAULT; + goto end; + } + + qcmd = kmalloc(sizeof(struct msm_queue_cmd) + + sizeof(struct msm_ctrl_cmd) + udata.length, + GFP_KERNEL); + if (!qcmd) { + rc = -ENOMEM; + goto end; + } + + qcmd->command = ctrlcmd = (struct msm_ctrl_cmd *)(qcmd + 1); + *ctrlcmd = udata; + if (udata.length > 0) { + ctrlcmd->value = ctrlcmd + 1; + if (copy_from_user(ctrlcmd->value, + (void *)udata.value, + udata.length)) { + ERR_COPY_FROM_USER(); + rc = -EFAULT; + kfree(qcmd); + goto end; + } + } else + ctrlcmd->value = NULL; + +end: + CDBG("msm_ctrl_cmd_done: end rc = %d\n", rc); + if (rc == 0) { + /* wake up control thread */ + spin_lock_irqsave(&ctrl_pmsm->ctrl_q.ctrl_status_q_lock, flags); + list_add_tail(&qcmd->list, &ctrl_pmsm->ctrl_q.ctrl_status_q); + wake_up(&ctrl_pmsm->ctrl_q.ctrl_status_wait); + spin_unlock_irqrestore(&ctrl_pmsm->ctrl_q.ctrl_status_q_lock, flags); + } + + return rc; +} + +static int msm_config_vfe(struct msm_sync *sync, void __user *arg) +{ + struct msm_vfe_cfg_cmd cfgcmd; + struct msm_pmem_region region[8]; + struct axidata axi_data; + void *data = NULL; + int rc = -EIO; + + memset(&axi_data, 0, sizeof(axi_data)); + + if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) { + ERR_COPY_FROM_USER(); + return -EFAULT; + } + + switch (cfgcmd.cmd_type) { + case CMD_STATS_ENABLE: + axi_data.bufnum1 = + msm_pmem_region_lookup(&sync->stats, + MSM_PMEM_AEC_AWB, ®ion[0], + NUM_WB_EXP_STAT_OUTPUT_BUFFERS); + if (!axi_data.bufnum1) { + pr_err("%s: pmem region lookup error\n", __func__); + return -EINVAL; + } + axi_data.region = ®ion[0]; + data = &axi_data; + break; + case CMD_STATS_AF_ENABLE: + axi_data.bufnum1 = + msm_pmem_region_lookup(&sync->stats, + MSM_PMEM_AF, ®ion[0], + NUM_AF_STAT_OUTPUT_BUFFERS); + if (!axi_data.bufnum1) { + pr_err("%s: pmem region lookup error\n", __func__); + return -EINVAL; + } + axi_data.region = ®ion[0]; + data = &axi_data; + break; + case CMD_GENERAL: + case CMD_STATS_DISABLE: + break; + default: + pr_err("%s: unknown command type %d\n", + __func__, cfgcmd.cmd_type); + return -EINVAL; + } + + + if (sync->vfefn.vfe_config) + rc = sync->vfefn.vfe_config(&cfgcmd, data); + + return rc; +} + +static int msm_frame_axi_cfg(struct msm_sync *sync, + struct msm_vfe_cfg_cmd *cfgcmd) +{ + int rc = -EIO; + struct axidata axi_data; + void *data = &axi_data; + struct msm_pmem_region region[8]; + int pmem_type; + + memset(&axi_data, 0, sizeof(axi_data)); + + switch (cfgcmd->cmd_type) { + case CMD_AXI_CFG_OUT1: + pmem_type = MSM_PMEM_OUTPUT1; + axi_data.bufnum1 = + msm_pmem_region_lookup(&sync->frame, pmem_type, + ®ion[0], 8); + if (!axi_data.bufnum1) { + pr_err("%s: pmem region lookup error\n", __func__); + return -EINVAL; + } + break; + + case CMD_AXI_CFG_OUT2: + pmem_type = MSM_PMEM_OUTPUT2; + axi_data.bufnum2 = + msm_pmem_region_lookup(&sync->frame, pmem_type, + ®ion[0], 8); + if (!axi_data.bufnum2) { + pr_err("%s: pmem region lookup error\n", __func__); + return -EINVAL; + } + break; + + case CMD_AXI_CFG_SNAP_O1_AND_O2: + pmem_type = MSM_PMEM_THUMBAIL; + axi_data.bufnum1 = + msm_pmem_region_lookup(&sync->frame, pmem_type, + ®ion[0], 8); + if (!axi_data.bufnum1) { + pr_err("%s: pmem region lookup error\n", __func__); + return -EINVAL; + } + + pmem_type = MSM_PMEM_MAINIMG; + axi_data.bufnum2 = + msm_pmem_region_lookup(&sync->frame, pmem_type, + ®ion[axi_data.bufnum1], 8); + if (!axi_data.bufnum2) { + pr_err("%s: pmem region lookup error\n", __func__); + return -EINVAL; + } + break; + + case CMD_RAW_PICT_AXI_CFG: + pmem_type = MSM_PMEM_RAW_MAINIMG; + axi_data.bufnum2 = + msm_pmem_region_lookup(&sync->frame, pmem_type, + ®ion[0], 8); + if (!axi_data.bufnum2) { + pr_err("%s: pmem region lookup error\n", __func__); + return -EINVAL; + } + break; + + case CMD_GENERAL: + data = NULL; + break; + + default: + pr_err("%s: unknown command type %d\n", + __func__, cfgcmd->cmd_type); + return -EINVAL; + } + + axi_data.region = ®ion[0]; + + /* send the AXI configuration command to driver */ + if (sync->vfefn.vfe_config) + rc = sync->vfefn.vfe_config(cfgcmd, data); + + return rc; +} + +static int msm_get_sensor_info(struct msm_sync *sync, void __user *arg) +{ + int rc = 0; + struct msm_camsensor_info info; + struct msm_camera_sensor_info *sdata; + + if (copy_from_user(&info, + arg, + sizeof(struct msm_camsensor_info))) { + ERR_COPY_FROM_USER(); + return -EFAULT; + } + + sdata = sync->pdev->dev.platform_data; + CDBG("sensor_name %s\n", sdata->sensor_name); + + memcpy(&info.name[0], + sdata->sensor_name, + MAX_SENSOR_NAME); + info.flash_enabled = sdata->flash_type != MSM_CAMERA_FLASH_NONE; + + /* copy back to user space */ + if (copy_to_user((void *)arg, + &info, + sizeof(struct msm_camsensor_info))) { + ERR_COPY_TO_USER(); + rc = -EFAULT; + } + + return rc; +} + +static int __msm_put_frame_buf(struct msm_sync *sync, + struct msm_frame *pb) +{ + unsigned long pphy; + struct msm_vfe_cfg_cmd cfgcmd; + + int rc = -EIO; + + pphy = msm_pmem_frame_vtop_lookup(sync, + pb->buffer, + pb->y_off, pb->cbcr_off, pb->fd); + + if (pphy != 0) { + CDBG("rel: vaddr = 0x%lx, paddr = 0x%lx\n", + pb->buffer, pphy); + cfgcmd.cmd_type = CMD_FRAME_BUF_RELEASE; + cfgcmd.value = (void *)pb; + if (sync->vfefn.vfe_config) + rc = sync->vfefn.vfe_config(&cfgcmd, &pphy); + } else { + pr_err("%s: msm_pmem_frame_vtop_lookup failed\n", + __func__); + rc = -EINVAL; + } + + return rc; +} + +static int msm_put_frame_buffer(struct msm_sync *sync, void __user *arg) +{ + struct msm_frame buf_t; + + if (copy_from_user(&buf_t, + arg, + sizeof(struct msm_frame))) { + ERR_COPY_FROM_USER(); + return -EFAULT; + } + + return __msm_put_frame_buf(sync, &buf_t); +} + +static int __msm_register_pmem(struct msm_sync *sync, + struct msm_pmem_info *pinfo) +{ + int rc = 0; + + switch (pinfo->type) { + case MSM_PMEM_OUTPUT1: + case MSM_PMEM_OUTPUT2: + case MSM_PMEM_THUMBAIL: + case MSM_PMEM_MAINIMG: + case MSM_PMEM_RAW_MAINIMG: + rc = msm_pmem_table_add(&sync->frame, pinfo); + break; + + case MSM_PMEM_AEC_AWB: + case MSM_PMEM_AF: + rc = msm_pmem_table_add(&sync->stats, pinfo); + break; + + default: + rc = -EINVAL; + break; + } + + return rc; +} + +static int msm_register_pmem(struct msm_sync *sync, void __user *arg) +{ + struct msm_pmem_info info; + + if (copy_from_user(&info, arg, sizeof(info))) { + ERR_COPY_FROM_USER(); + return -EFAULT; + } + + return __msm_register_pmem(sync, &info); +} + +static int msm_stats_axi_cfg(struct msm_sync *sync, + struct msm_vfe_cfg_cmd *cfgcmd) +{ + int rc = -EIO; + struct axidata axi_data; + void *data = &axi_data; + + struct msm_pmem_region region[3]; + int pmem_type = MSM_PMEM_MAX; + + memset(&axi_data, 0, sizeof(axi_data)); + + switch (cfgcmd->cmd_type) { + case CMD_STATS_AXI_CFG: + pmem_type = MSM_PMEM_AEC_AWB; + break; + case CMD_STATS_AF_AXI_CFG: + pmem_type = MSM_PMEM_AF; + break; + case CMD_GENERAL: + data = NULL; + break; + default: + pr_err("%s: unknown command type %d\n", + __func__, cfgcmd->cmd_type); + return -EINVAL; + } + + if (cfgcmd->cmd_type != CMD_GENERAL) { + axi_data.bufnum1 = + msm_pmem_region_lookup(&sync->stats, pmem_type, + ®ion[0], NUM_WB_EXP_STAT_OUTPUT_BUFFERS); + if (!axi_data.bufnum1) { + pr_err("%s: pmem region lookup error\n", __func__); + return -EINVAL; + } + axi_data.region = ®ion[0]; + } + + /* send the AEC/AWB STATS configuration command to driver */ + if (sync->vfefn.vfe_config) + rc = sync->vfefn.vfe_config(cfgcmd, &axi_data); + + return rc; +} + +static int msm_put_stats_buffer(struct msm_sync *sync, void __user *arg) +{ + int rc = -EIO; + + struct msm_stats_buf buf; + unsigned long pphy; + struct msm_vfe_cfg_cmd cfgcmd; + + if (copy_from_user(&buf, arg, + sizeof(struct msm_stats_buf))) { + ERR_COPY_FROM_USER(); + return -EFAULT; + } + + CDBG("msm_put_stats_buffer\n"); + pphy = msm_pmem_stats_vtop_lookup(sync, buf.buffer, buf.fd); + + if (pphy != 0) { + if (buf.type == STAT_AEAW) + cfgcmd.cmd_type = CMD_STATS_BUF_RELEASE; + else if (buf.type == STAT_AF) + cfgcmd.cmd_type = CMD_STATS_AF_BUF_RELEASE; + else { + pr_err("%s: invalid buf type %d\n", + __func__, + buf.type); + rc = -EINVAL; + goto put_done; + } + + cfgcmd.value = (void *)&buf; + + if (sync->vfefn.vfe_config) { + rc = sync->vfefn.vfe_config(&cfgcmd, &pphy); + if (rc < 0) + pr_err("msm_put_stats_buffer: "\ + "vfe_config err %d\n", rc); + } else + pr_err("msm_put_stats_buffer: vfe_config is NULL\n"); + } else { + pr_err("msm_put_stats_buffer: NULL physical address\n"); + rc = -EINVAL; + } + +put_done: + return rc; +} + +static int msm_axi_config(struct msm_sync *sync, void __user *arg) +{ + struct msm_vfe_cfg_cmd cfgcmd; + + if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) { + ERR_COPY_FROM_USER(); + return -EFAULT; + } + + switch (cfgcmd.cmd_type) { + case CMD_AXI_CFG_OUT1: + case CMD_AXI_CFG_OUT2: + case CMD_AXI_CFG_SNAP_O1_AND_O2: + case CMD_RAW_PICT_AXI_CFG: + return msm_frame_axi_cfg(sync, &cfgcmd); + + case CMD_STATS_AXI_CFG: + case CMD_STATS_AF_AXI_CFG: + return msm_stats_axi_cfg(sync, &cfgcmd); + + default: + pr_err("%s: unknown command type %d\n", + __func__, + cfgcmd.cmd_type); + return -EINVAL; + } + + return 0; +} + +static int __msm_get_pic(struct msm_sync *sync, struct msm_ctrl_cmd *ctrl) +{ + unsigned long flags; + int rc = 0; + int tm; + + struct msm_queue_cmd *qcmd = NULL; + + tm = (int)ctrl->timeout_ms; + + rc = wait_event_interruptible_timeout( + sync->pict_frame_wait, + !list_empty_careful(&sync->pict_frame_q), + msecs_to_jiffies(tm)); + if (list_empty_careful(&sync->pict_frame_q)) { + if (rc == 0) + return -ETIMEDOUT; + if (rc < 0) { + pr_err("msm_camera_get_picture, rc = %d\n", rc); + return rc; + } + } + + spin_lock_irqsave(&sync->pict_frame_q_lock, flags); + BUG_ON(list_empty(&sync->pict_frame_q)); + qcmd = list_first_entry(&sync->pict_frame_q, + struct msm_queue_cmd, list); + list_del_init(&qcmd->list); + spin_unlock_irqrestore(&sync->pict_frame_q_lock, flags); + + if (qcmd->command != NULL) { + struct msm_ctrl_cmd *q = + (struct msm_ctrl_cmd *)qcmd->command; + ctrl->type = q->type; + ctrl->status = q->status; + } else { + ctrl->type = -1; + ctrl->status = -1; + } + + kfree(qcmd); + return rc; +} + +static int msm_get_pic(struct msm_sync *sync, void __user *arg) +{ + struct msm_ctrl_cmd ctrlcmd_t; + int rc; + + if (copy_from_user(&ctrlcmd_t, + arg, + sizeof(struct msm_ctrl_cmd))) { + ERR_COPY_FROM_USER(); + return -EFAULT; + } + + rc = __msm_get_pic(sync, &ctrlcmd_t); + if (rc < 0) + return rc; + + if (sync->croplen) { + if (ctrlcmd_t.length < sync->croplen) { + pr_err("msm_get_pic: invalid len %d\n", + ctrlcmd_t.length); + return -EINVAL; + } + if (copy_to_user(ctrlcmd_t.value, + sync->cropinfo, + sync->croplen)) { + ERR_COPY_TO_USER(); + return -EFAULT; + } + } + + if (copy_to_user((void *)arg, + &ctrlcmd_t, + sizeof(struct msm_ctrl_cmd))) { + ERR_COPY_TO_USER(); + return -EFAULT; + } + return 0; +} + +static int msm_set_crop(struct msm_sync *sync, void __user *arg) +{ + struct crop_info crop; + + if (copy_from_user(&crop, + arg, + sizeof(struct crop_info))) { + ERR_COPY_FROM_USER(); + return -EFAULT; + } + + if (!sync->croplen) { + sync->cropinfo = kmalloc(crop.len, GFP_KERNEL); + if (!sync->cropinfo) + return -ENOMEM; + } else if (sync->croplen < crop.len) + return -EINVAL; + + if (copy_from_user(sync->cropinfo, + crop.info, + crop.len)) { + ERR_COPY_FROM_USER(); + kfree(sync->cropinfo); + return -EFAULT; + } + + sync->croplen = crop.len; + + return 0; +} + +static int msm_pict_pp_done(struct msm_sync *sync, void __user *arg) +{ + struct msm_ctrl_cmd udata; + struct msm_ctrl_cmd *ctrlcmd = NULL; + struct msm_queue_cmd *qcmd = NULL; + unsigned long flags; + int rc = 0; + + if (!sync->pict_pp) + return -EINVAL; + + if (copy_from_user(&udata, arg, sizeof(struct msm_ctrl_cmd))) { + ERR_COPY_FROM_USER(); + rc = -EFAULT; + goto pp_fail; + } + + qcmd = kmalloc(sizeof(struct msm_queue_cmd) + + sizeof(struct msm_ctrl_cmd), + GFP_KERNEL); + if (!qcmd) { + rc = -ENOMEM; + goto pp_fail; + } + + qcmd->type = MSM_CAM_Q_VFE_MSG; + qcmd->command = ctrlcmd = (struct msm_ctrl_cmd *)(qcmd + 1); + memset(ctrlcmd, 0, sizeof(struct msm_ctrl_cmd)); + ctrlcmd->type = udata.type; + ctrlcmd->status = udata.status; + + spin_lock_irqsave(&sync->pict_frame_q_lock, flags); + list_add_tail(&qcmd->list, &sync->pict_frame_q); + spin_unlock_irqrestore(&sync->pict_frame_q_lock, flags); + wake_up(&sync->pict_frame_wait); + +pp_fail: + return rc; +} + +static long msm_ioctl_common(struct msm_device *pmsm, + unsigned int cmd, + void __user *argp) +{ + CDBG("msm_ioctl_common\n"); + switch (cmd) { + case MSM_CAM_IOCTL_REGISTER_PMEM: + return msm_register_pmem(pmsm->sync, argp); + case MSM_CAM_IOCTL_UNREGISTER_PMEM: + return msm_pmem_table_del(pmsm->sync, argp); + default: + return -EINVAL; + } +} + +static long msm_ioctl_config(struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int rc = -EINVAL; + void __user *argp = (void __user *)arg; + struct msm_device *pmsm = filep->private_data; + + CDBG("msm_ioctl_config cmd = %d\n", _IOC_NR(cmd)); + + switch (cmd) { + case MSM_CAM_IOCTL_GET_SENSOR_INFO: + rc = msm_get_sensor_info(pmsm->sync, argp); + break; + + case MSM_CAM_IOCTL_CONFIG_VFE: + /* Coming from config thread for update */ + rc = msm_config_vfe(pmsm->sync, argp); + break; + + case MSM_CAM_IOCTL_GET_STATS: + /* Coming from config thread wait + * for vfe statistics and control requests */ + rc = msm_get_stats(pmsm->sync, argp); + break; + + case MSM_CAM_IOCTL_ENABLE_VFE: + /* This request comes from control thread: + * enable either QCAMTASK or VFETASK */ + rc = msm_enable_vfe(pmsm->sync, argp); + break; + + case MSM_CAM_IOCTL_DISABLE_VFE: + /* This request comes from control thread: + * disable either QCAMTASK or VFETASK */ + rc = msm_disable_vfe(pmsm->sync, argp); + break; + + case MSM_CAM_IOCTL_VFE_APPS_RESET: + msm_camio_vfe_blk_reset(); + rc = 0; + break; + + case MSM_CAM_IOCTL_RELEASE_STATS_BUFFER: + rc = msm_put_stats_buffer(pmsm->sync, argp); + break; + + case MSM_CAM_IOCTL_AXI_CONFIG: + rc = msm_axi_config(pmsm->sync, argp); + break; + + case MSM_CAM_IOCTL_SET_CROP: + rc = msm_set_crop(pmsm->sync, argp); + break; + + case MSM_CAM_IOCTL_PICT_PP: { + uint8_t enable; + if (copy_from_user(&enable, argp, sizeof(enable))) { + ERR_COPY_FROM_USER(); + rc = -EFAULT; + } else { + pmsm->sync->pict_pp = enable; + rc = 0; + } + break; + } + + case MSM_CAM_IOCTL_PICT_PP_DONE: + rc = msm_pict_pp_done(pmsm->sync, argp); + break; + + case MSM_CAM_IOCTL_SENSOR_IO_CFG: + rc = pmsm->sync->sctrl.s_config(argp); + break; + + case MSM_CAM_IOCTL_FLASH_LED_CFG: { + uint32_t led_state; + if (copy_from_user(&led_state, argp, sizeof(led_state))) { + ERR_COPY_FROM_USER(); + rc = -EFAULT; + } else + rc = msm_camera_flash_set_led_state(led_state); + break; + } + + default: + rc = msm_ioctl_common(pmsm, cmd, argp); + break; + } + + CDBG("msm_ioctl_config cmd = %d DONE\n", _IOC_NR(cmd)); + return rc; +} + +static int msm_unblock_poll_frame(struct msm_sync *); + +static long msm_ioctl_frame(struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int rc = -EINVAL; + void __user *argp = (void __user *)arg; + struct msm_device *pmsm = filep->private_data; + + + switch (cmd) { + case MSM_CAM_IOCTL_GETFRAME: + /* Coming from frame thread to get frame + * after SELECT is done */ + rc = msm_get_frame(pmsm->sync, argp); + break; + case MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER: + rc = msm_put_frame_buffer(pmsm->sync, argp); + break; + case MSM_CAM_IOCTL_UNBLOCK_POLL_FRAME: + rc = msm_unblock_poll_frame(pmsm->sync); + break; + default: + break; + } + + return rc; +} + + +static long msm_ioctl_control(struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int rc = -EINVAL; + void __user *argp = (void __user *)arg; + struct msm_control_device *ctrl_pmsm = filep->private_data; + struct msm_device *pmsm = ctrl_pmsm->pmsm; + + switch (cmd) { + case MSM_CAM_IOCTL_CTRL_COMMAND: + /* Coming from control thread, may need to wait for + * command status */ + rc = msm_control(ctrl_pmsm, 1, argp); + break; + case MSM_CAM_IOCTL_CTRL_COMMAND_2: + /* Sends a message, returns immediately */ + rc = msm_control(ctrl_pmsm, 0, argp); + break; + case MSM_CAM_IOCTL_CTRL_CMD_DONE: + /* Config thread calls the control thread to notify it + * of the result of a MSM_CAM_IOCTL_CTRL_COMMAND. + */ + rc = msm_ctrl_cmd_done(ctrl_pmsm, argp); + break; + case MSM_CAM_IOCTL_GET_PICTURE: + rc = msm_get_pic(pmsm->sync, argp); + break; + default: + rc = msm_ioctl_common(pmsm, cmd, argp); + break; + } + + return rc; +} + +static int __msm_release(struct msm_sync *sync) +{ + struct msm_pmem_region *region; + struct hlist_node *hnode; + struct hlist_node *n; + + mutex_lock(&sync->lock); + if (sync->opencnt) + sync->opencnt--; + + if (!sync->opencnt) { + /* need to clean up system resource */ + if (sync->vfefn.vfe_release) + sync->vfefn.vfe_release(sync->pdev); + + if (sync->cropinfo) { + kfree(sync->cropinfo); + sync->cropinfo = NULL; + sync->croplen = 0; + } + + hlist_for_each_entry_safe(region, hnode, n, + &sync->frame, list) { + hlist_del(hnode); + put_pmem_file(region->file); + kfree(region); + } + + hlist_for_each_entry_safe(region, hnode, n, + &sync->stats, list) { + hlist_del(hnode); + put_pmem_file(region->file); + kfree(region); + } + + MSM_DRAIN_QUEUE(sync, msg_event_q); + MSM_DRAIN_QUEUE(sync, prev_frame_q); + MSM_DRAIN_QUEUE(sync, pict_frame_q); + + sync->sctrl.s_release(); + + sync->apps_id = NULL; + CDBG("msm_release completed!\n"); + } + mutex_unlock(&sync->lock); + + return 0; +} + +static int msm_release_config(struct inode *node, struct file *filep) +{ + int rc; + struct msm_device *pmsm = filep->private_data; + printk("msm_camera: RELEASE %s\n", filep->f_path.dentry->d_name.name); + rc = __msm_release(pmsm->sync); + atomic_set(&pmsm->opened, 0); + return rc; +} + +static int msm_release_control(struct inode *node, struct file *filep) +{ + int rc; + struct msm_control_device *ctrl_pmsm = filep->private_data; + struct msm_device *pmsm = ctrl_pmsm->pmsm; + printk(KERN_INFO "msm_camera: RELEASE %s\n", + filep->f_path.dentry->d_name.name); + rc = __msm_release(pmsm->sync); + if (!rc) { + MSM_DRAIN_QUEUE(&ctrl_pmsm->ctrl_q, ctrl_status_q); + MSM_DRAIN_QUEUE(pmsm->sync, pict_frame_q); + } + kfree(ctrl_pmsm); + return rc; +} + +static int msm_release_frame(struct inode *node, struct file *filep) +{ + int rc; + struct msm_device *pmsm = filep->private_data; + printk(KERN_INFO "msm_camera: RELEASE %s\n", + filep->f_path.dentry->d_name.name); + rc = __msm_release(pmsm->sync); + if (!rc) { + MSM_DRAIN_QUEUE(pmsm->sync, prev_frame_q); + atomic_set(&pmsm->opened, 0); + } + return rc; +} + +static int msm_unblock_poll_frame(struct msm_sync *sync) +{ + unsigned long flags; + CDBG("msm_unblock_poll_frame\n"); + spin_lock_irqsave(&sync->prev_frame_q_lock, flags); + sync->unblock_poll_frame = 1; + wake_up(&sync->prev_frame_wait); + spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags); + return 0; +} + +static unsigned int __msm_poll_frame(struct msm_sync *sync, + struct file *filep, + struct poll_table_struct *pll_table) +{ + int rc = 0; + unsigned long flags; + + poll_wait(filep, &sync->prev_frame_wait, pll_table); + + spin_lock_irqsave(&sync->prev_frame_q_lock, flags); + if (!list_empty_careful(&sync->prev_frame_q)) + /* frame ready */ + rc = POLLIN | POLLRDNORM; + if (sync->unblock_poll_frame) { + CDBG("%s: sync->unblock_poll_frame is true\n", __func__); + rc |= POLLPRI; + sync->unblock_poll_frame = 0; + } + spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags); + + return rc; +} + +static unsigned int msm_poll_frame(struct file *filep, + struct poll_table_struct *pll_table) +{ + struct msm_device *pmsm = filep->private_data; + return __msm_poll_frame(pmsm->sync, filep, pll_table); +} + +/* + * This function executes in interrupt context. + */ + +static void *msm_vfe_sync_alloc(int size, + void *syncdata __attribute__((unused))) +{ + struct msm_queue_cmd *qcmd = + kmalloc(sizeof(struct msm_queue_cmd) + size, GFP_ATOMIC); + return qcmd ? qcmd + 1 : NULL; +} + +/* + * This function executes in interrupt context. + */ + +static void msm_vfe_sync(struct msm_vfe_resp *vdata, + enum msm_queue qtype, void *syncdata) +{ + struct msm_queue_cmd *qcmd = NULL; + struct msm_queue_cmd *qcmd_frame = NULL; + struct msm_vfe_phy_info *fphy; + + unsigned long flags; + struct msm_sync *sync = (struct msm_sync *)syncdata; + if (!sync) { + pr_err("msm_camera: no context in dsp callback.\n"); + return; + } + + qcmd = ((struct msm_queue_cmd *)vdata) - 1; + qcmd->type = qtype; + + if (qtype == MSM_CAM_Q_VFE_MSG) { + switch (vdata->type) { + case VFE_MSG_OUTPUT1: + case VFE_MSG_OUTPUT2: + qcmd_frame = + kmalloc(sizeof(struct msm_queue_cmd) + + sizeof(struct msm_vfe_phy_info), + GFP_ATOMIC); + if (!qcmd_frame) + goto mem_fail; + fphy = (struct msm_vfe_phy_info *)(qcmd_frame + 1); + *fphy = vdata->phy; + + qcmd_frame->type = MSM_CAM_Q_VFE_MSG; + qcmd_frame->command = fphy; + + CDBG("qcmd_frame= 0x%x phy_y= 0x%x, phy_cbcr= 0x%x\n", + (int) qcmd_frame, fphy->y_phy, fphy->cbcr_phy); + + spin_lock_irqsave(&sync->prev_frame_q_lock, flags); + list_add_tail(&qcmd_frame->list, &sync->prev_frame_q); + wake_up(&sync->prev_frame_wait); + spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags); + CDBG("woke up frame thread\n"); + break; + case VFE_MSG_SNAPSHOT: + if (sync->pict_pp) + break; + + CDBG("snapshot pp = %d\n", sync->pict_pp); + qcmd_frame = + kmalloc(sizeof(struct msm_queue_cmd), + GFP_ATOMIC); + if (!qcmd_frame) + goto mem_fail; + qcmd_frame->type = MSM_CAM_Q_VFE_MSG; + qcmd_frame->command = NULL; + spin_lock_irqsave(&sync->pict_frame_q_lock, + flags); + list_add_tail(&qcmd_frame->list, &sync->pict_frame_q); + wake_up(&sync->pict_frame_wait); + spin_unlock_irqrestore(&sync->pict_frame_q_lock, flags); + CDBG("woke up picture thread\n"); + break; + default: + CDBG("%s: qtype = %d not handled\n", + __func__, vdata->type); + break; + } + } + + qcmd->command = (void *)vdata; + CDBG("vdata->type = %d\n", vdata->type); + + spin_lock_irqsave(&sync->msg_event_q_lock, flags); + list_add_tail(&qcmd->list, &sync->msg_event_q); + wake_up(&sync->msg_event_wait); + spin_unlock_irqrestore(&sync->msg_event_q_lock, flags); + CDBG("woke up config thread\n"); + return; + +mem_fail: + kfree(qcmd); +} + +static struct msm_vfe_callback msm_vfe_s = { + .vfe_resp = msm_vfe_sync, + .vfe_alloc = msm_vfe_sync_alloc, +}; + +static int __msm_open(struct msm_sync *sync, const char *const apps_id) +{ + int rc = 0; + + mutex_lock(&sync->lock); + if (sync->apps_id && strcmp(sync->apps_id, apps_id)) { + pr_err("msm_camera(%s): sensor %s is already opened for %s\n", + apps_id, + sync->sdata->sensor_name, + sync->apps_id); + rc = -EBUSY; + goto msm_open_done; + } + + sync->apps_id = apps_id; + + if (!sync->opencnt) { + + msm_camvfe_fn_init(&sync->vfefn, sync); + if (sync->vfefn.vfe_init) { + rc = sync->vfefn.vfe_init(&msm_vfe_s, + sync->pdev); + if (rc < 0) { + pr_err("vfe_init failed at %d\n", rc); + goto msm_open_done; + } + rc = sync->sctrl.s_init(sync->sdata); + if (rc < 0) { + pr_err("sensor init failed: %d\n", rc); + goto msm_open_done; + } + } else { + pr_err("no sensor init func\n"); + rc = -ENODEV; + goto msm_open_done; + } + + if (rc >= 0) { + INIT_HLIST_HEAD(&sync->frame); + INIT_HLIST_HEAD(&sync->stats); + sync->unblock_poll_frame = 0; + } + } + sync->opencnt++; + +msm_open_done: + mutex_unlock(&sync->lock); + return rc; +} + +static int msm_open_common(struct inode *inode, struct file *filep, + int once) +{ + int rc; + struct msm_device *pmsm = + container_of(inode->i_cdev, struct msm_device, cdev); + + CDBG("msm_camera: open %s\n", filep->f_path.dentry->d_name.name); + + if (atomic_cmpxchg(&pmsm->opened, 0, 1) && once) { + pr_err("msm_camera: %s is already opened.\n", + filep->f_path.dentry->d_name.name); + return -EBUSY; + } + + rc = nonseekable_open(inode, filep); + if (rc < 0) { + pr_err("msm_open: nonseekable_open error %d\n", rc); + return rc; + } + + rc = __msm_open(pmsm->sync, MSM_APPS_ID_PROP); + if (rc < 0) + return rc; + + filep->private_data = pmsm; + + CDBG("msm_open() open: rc = %d\n", rc); + return rc; +} + +static int msm_open(struct inode *inode, struct file *filep) +{ + return msm_open_common(inode, filep, 1); +} + +static int msm_open_control(struct inode *inode, struct file *filep) +{ + int rc; + + struct msm_control_device *ctrl_pmsm = + kmalloc(sizeof(struct msm_control_device), GFP_KERNEL); + if (!ctrl_pmsm) + return -ENOMEM; + + rc = msm_open_common(inode, filep, 0); + if (rc < 0) { + kfree(ctrl_pmsm); + return rc; + } + + ctrl_pmsm->pmsm = filep->private_data; + filep->private_data = ctrl_pmsm; + spin_lock_init(&ctrl_pmsm->ctrl_q.ctrl_status_q_lock); + INIT_LIST_HEAD(&ctrl_pmsm->ctrl_q.ctrl_status_q); + init_waitqueue_head(&ctrl_pmsm->ctrl_q.ctrl_status_wait); + + CDBG("msm_open() open: rc = %d\n", rc); + return rc; +} + +static int __msm_v4l2_control(struct msm_sync *sync, + struct msm_ctrl_cmd *out) +{ + int rc = 0; + + struct msm_queue_cmd *qcmd = NULL, *rcmd = NULL; + struct msm_ctrl_cmd *ctrl; + struct msm_control_device_queue FIXME; + + /* wake up config thread, 4 is for V4L2 application */ + qcmd = kmalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL); + if (!qcmd) { + pr_err("msm_control: cannot allocate buffer\n"); + rc = -ENOMEM; + goto end; + } + qcmd->type = MSM_CAM_Q_V4L2_REQ; + qcmd->command = out; + + rcmd = __msm_control(sync, &FIXME, qcmd, out->timeout_ms); + if (IS_ERR(rcmd)) { + rc = PTR_ERR(rcmd); + goto end; + } + + ctrl = (struct msm_ctrl_cmd *)(rcmd->command); + /* FIXME: we should just set out->length = ctrl->length; */ + BUG_ON(out->length < ctrl->length); + memcpy(out->value, ctrl->value, ctrl->length); + +end: + kfree(rcmd); + CDBG("__msm_v4l2_control: end rc = %d\n", rc); + return rc; +} + +static const struct file_operations msm_fops_config = { + .owner = THIS_MODULE, + .open = msm_open, + .unlocked_ioctl = msm_ioctl_config, + .release = msm_release_config, + .llseek = no_llseek, +}; + +static const struct file_operations msm_fops_control = { + .owner = THIS_MODULE, + .open = msm_open_control, + .unlocked_ioctl = msm_ioctl_control, + .release = msm_release_control, + .llseek = no_llseek, +}; + +static const struct file_operations msm_fops_frame = { + .owner = THIS_MODULE, + .open = msm_open, + .unlocked_ioctl = msm_ioctl_frame, + .release = msm_release_frame, + .poll = msm_poll_frame, + .llseek = no_llseek, +}; + +static int msm_setup_cdev(struct msm_device *msm, + int node, + dev_t devno, + const char *suffix, + const struct file_operations *fops) +{ + int rc = -ENODEV; + + struct device *device = + device_create(msm_class, NULL, + devno, NULL, + "%s%d", suffix, node); + + if (IS_ERR(device)) { + rc = PTR_ERR(device); + pr_err("msm_camera: error creating device: %d\n", rc); + return rc; + } + + cdev_init(&msm->cdev, fops); + msm->cdev.owner = THIS_MODULE; + + rc = cdev_add(&msm->cdev, devno, 1); + if (rc < 0) { + pr_err("msm_camera: error adding cdev: %d\n", rc); + device_destroy(msm_class, devno); + return rc; + } + + return rc; +} + +static int msm_tear_down_cdev(struct msm_device *msm, dev_t devno) +{ + cdev_del(&msm->cdev); + device_destroy(msm_class, devno); + return 0; +} + +int msm_v4l2_register(struct msm_v4l2_driver *drv) +{ + /* FIXME: support multiple sensors */ + if (list_empty(&msm_sensors)) + return -ENODEV; + + drv->sync = list_first_entry(&msm_sensors, struct msm_sync, list); + drv->open = __msm_open; + drv->release = __msm_release; + drv->ctrl = __msm_v4l2_control; + drv->reg_pmem = __msm_register_pmem; + drv->get_frame = __msm_get_frame; + drv->put_frame = __msm_put_frame_buf; + drv->get_pict = __msm_get_pic; + drv->drv_poll = __msm_poll_frame; + + return 0; +} +EXPORT_SYMBOL(msm_v4l2_register); + +int msm_v4l2_unregister(struct msm_v4l2_driver *drv) +{ + drv->sync = NULL; + return 0; +} +EXPORT_SYMBOL(msm_v4l2_unregister); + +static int msm_sync_init(struct msm_sync *sync, + struct platform_device *pdev, + int (*sensor_probe)(const struct msm_camera_sensor_info *, + struct msm_sensor_ctrl *)) +{ + int rc = 0; + struct msm_sensor_ctrl sctrl; + sync->sdata = pdev->dev.platform_data; + + spin_lock_init(&sync->msg_event_q_lock); + INIT_LIST_HEAD(&sync->msg_event_q); + init_waitqueue_head(&sync->msg_event_wait); + + spin_lock_init(&sync->prev_frame_q_lock); + INIT_LIST_HEAD(&sync->prev_frame_q); + init_waitqueue_head(&sync->prev_frame_wait); + + spin_lock_init(&sync->pict_frame_q_lock); + INIT_LIST_HEAD(&sync->pict_frame_q); + init_waitqueue_head(&sync->pict_frame_wait); + + rc = msm_camio_probe_on(pdev); + if (rc < 0) + return rc; + rc = sensor_probe(sync->sdata, &sctrl); + if (rc >= 0) { + sync->pdev = pdev; + sync->sctrl = sctrl; + } + msm_camio_probe_off(pdev); + if (rc < 0) { + pr_err("msm_camera: failed to initialize %s\n", + sync->sdata->sensor_name); + return rc; + } + + sync->opencnt = 0; + mutex_init(&sync->lock); + CDBG("initialized %s\n", sync->sdata->sensor_name); + return rc; +} + +static int msm_sync_destroy(struct msm_sync *sync) +{ + return 0; +} + +static int msm_device_init(struct msm_device *pmsm, + struct msm_sync *sync, + int node) +{ + int dev_num = 3 * node; + int rc = msm_setup_cdev(pmsm, node, + MKDEV(MAJOR(msm_devno), dev_num), + "control", &msm_fops_control); + if (rc < 0) { + pr_err("error creating control node: %d\n", rc); + return rc; + } + + rc = msm_setup_cdev(pmsm + 1, node, + MKDEV(MAJOR(msm_devno), dev_num + 1), + "config", &msm_fops_config); + if (rc < 0) { + pr_err("error creating config node: %d\n", rc); + msm_tear_down_cdev(pmsm, MKDEV(MAJOR(msm_devno), + dev_num)); + return rc; + } + + rc = msm_setup_cdev(pmsm + 2, node, + MKDEV(MAJOR(msm_devno), dev_num + 2), + "frame", &msm_fops_frame); + if (rc < 0) { + pr_err("error creating frame node: %d\n", rc); + msm_tear_down_cdev(pmsm, + MKDEV(MAJOR(msm_devno), dev_num)); + msm_tear_down_cdev(pmsm + 1, + MKDEV(MAJOR(msm_devno), dev_num + 1)); + return rc; + } + + atomic_set(&pmsm[0].opened, 0); + atomic_set(&pmsm[1].opened, 0); + atomic_set(&pmsm[2].opened, 0); + + pmsm[0].sync = sync; + pmsm[1].sync = sync; + pmsm[2].sync = sync; + + return rc; +} + +int msm_camera_drv_start(struct platform_device *dev, + int (*sensor_probe)(const struct msm_camera_sensor_info *, + struct msm_sensor_ctrl *)) +{ + struct msm_device *pmsm = NULL; + struct msm_sync *sync; + int rc = -ENODEV; + static int camera_node; + + if (camera_node >= MSM_MAX_CAMERA_SENSORS) { + pr_err("msm_camera: too many camera sensors\n"); + return rc; + } + + if (!msm_class) { + /* There are three device nodes per sensor */ + rc = alloc_chrdev_region(&msm_devno, 0, + 3 * MSM_MAX_CAMERA_SENSORS, + "msm_camera"); + if (rc < 0) { + pr_err("msm_camera: failed to allocate chrdev: %d\n", + rc); + return rc; + } + + msm_class = class_create(THIS_MODULE, "msm_camera"); + if (IS_ERR(msm_class)) { + rc = PTR_ERR(msm_class); + pr_err("msm_camera: create device class failed: %d\n", + rc); + return rc; + } + } + + pmsm = kzalloc(sizeof(struct msm_device) * 3 + + sizeof(struct msm_sync), GFP_ATOMIC); + if (!pmsm) + return -ENOMEM; + sync = (struct msm_sync *)(pmsm + 3); + + rc = msm_sync_init(sync, dev, sensor_probe); + if (rc < 0) { + kfree(pmsm); + return rc; + } + + CDBG("setting camera node %d\n", camera_node); + rc = msm_device_init(pmsm, sync, camera_node); + if (rc < 0) { + msm_sync_destroy(sync); + kfree(pmsm); + return rc; + } + + camera_node++; + list_add(&sync->list, &msm_sensors); + return rc; +} +EXPORT_SYMBOL(msm_camera_drv_start); diff --git a/trunk/drivers/staging/dream/camera/msm_io7x.c b/trunk/drivers/staging/dream/camera/msm_io7x.c new file mode 100644 index 000000000000..55c020bb7afa --- /dev/null +++ b/trunk/drivers/staging/dream/camera/msm_io7x.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2008-2009 QUALCOMM Incorporated + */ + +#include +#include +#include +#include +#include +#include + +#define CAMIF_CFG_RMSK 0x1fffff +#define CAM_SEL_BMSK 0x2 +#define CAM_PCLK_SRC_SEL_BMSK 0x60000 +#define CAM_PCLK_INVERT_BMSK 0x80000 +#define CAM_PAD_REG_SW_RESET_BMSK 0x100000 + +#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000 +#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000 +#define MDDI_CLK_CHICKEN_BIT_BMSK 0x80 + +#define CAM_SEL_SHFT 0x1 +#define CAM_PCLK_SRC_SEL_SHFT 0x11 +#define CAM_PCLK_INVERT_SHFT 0x13 +#define CAM_PAD_REG_SW_RESET_SHFT 0x14 + +#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10 +#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF +#define MDDI_CLK_CHICKEN_BIT_SHFT 0x7 +#define APPS_RESET_OFFSET 0x00000210 + +static struct clk *camio_vfe_mdc_clk; +static struct clk *camio_mdc_clk; +static struct clk *camio_vfe_clk; + +static struct msm_camera_io_ext camio_ext; +static struct resource *appio, *mdcio; +void __iomem *appbase, *mdcbase; + +static struct msm_camera_io_ext camio_ext; +static struct resource *appio, *mdcio; +void __iomem *appbase, *mdcbase; + +extern int clk_set_flags(struct clk *clk, unsigned long flags); + +int msm_camio_clk_enable(enum msm_camio_clk_type clktype) +{ + int rc = -1; + struct clk *clk = NULL; + + switch (clktype) { + case CAMIO_VFE_MDC_CLK: + clk = camio_vfe_mdc_clk = clk_get(NULL, "vfe_mdc_clk"); + break; + + case CAMIO_MDC_CLK: + clk = camio_mdc_clk = clk_get(NULL, "mdc_clk"); + break; + + case CAMIO_VFE_CLK: + clk = camio_vfe_clk = clk_get(NULL, "vfe_clk"); + break; + + default: + break; + } + + if (!IS_ERR(clk)) { + clk_enable(clk); + rc = 0; + } + + return rc; +} + +int msm_camio_clk_disable(enum msm_camio_clk_type clktype) +{ + int rc = -1; + struct clk *clk = NULL; + + switch (clktype) { + case CAMIO_VFE_MDC_CLK: + clk = camio_vfe_mdc_clk; + break; + + case CAMIO_MDC_CLK: + clk = camio_mdc_clk; + break; + + case CAMIO_VFE_CLK: + clk = camio_vfe_clk; + break; + + default: + break; + } + + if (!IS_ERR(clk)) { + clk_disable(clk); + clk_put(clk); + rc = 0; + } + + return rc; +} + +void msm_camio_clk_rate_set(int rate) +{ + struct clk *clk = camio_vfe_clk; + + if (clk != ERR_PTR(-ENOENT)) + clk_set_rate(clk, rate); +} + +int msm_camio_enable(struct platform_device *pdev) +{ + int rc = 0; + struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data; + struct msm_camera_device_platform_data *camdev = sinfo->pdata; + + camio_ext = camdev->ioext; + + appio = request_mem_region(camio_ext.appphy, + camio_ext.appsz, pdev->name); + if (!appio) { + rc = -EBUSY; + goto enable_fail; + } + + appbase = ioremap(camio_ext.appphy, + camio_ext.appsz); + if (!appbase) { + rc = -ENOMEM; + goto apps_no_mem; + } + + mdcio = request_mem_region(camio_ext.mdcphy, + camio_ext.mdcsz, pdev->name); + if (!mdcio) { + rc = -EBUSY; + goto mdc_busy; + } + + mdcbase = ioremap(camio_ext.mdcphy, + camio_ext.mdcsz); + if (!mdcbase) { + rc = -ENOMEM; + goto mdc_no_mem; + } + + camdev->camera_gpio_on(); + + msm_camio_clk_enable(CAMIO_VFE_CLK); + msm_camio_clk_enable(CAMIO_MDC_CLK); + msm_camio_clk_enable(CAMIO_VFE_MDC_CLK); + return 0; + +mdc_no_mem: + release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz); +mdc_busy: + iounmap(appbase); +apps_no_mem: + release_mem_region(camio_ext.appphy, camio_ext.appsz); +enable_fail: + return rc; +} + +void msm_camio_disable(struct platform_device *pdev) +{ + struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data; + struct msm_camera_device_platform_data *camdev = sinfo->pdata; + + iounmap(mdcbase); + release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz); + iounmap(appbase); + release_mem_region(camio_ext.appphy, camio_ext.appsz); + + camdev->camera_gpio_off(); + + msm_camio_clk_disable(CAMIO_VFE_CLK); + msm_camio_clk_disable(CAMIO_MDC_CLK); + msm_camio_clk_disable(CAMIO_VFE_MDC_CLK); +} + +void msm_camio_camif_pad_reg_reset(void) +{ + uint32_t reg; + uint32_t mask, value; + + /* select CLKRGM_VFE_SRC_CAM_VFE_SRC: internal source */ + msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL); + + reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; + + mask = CAM_SEL_BMSK | + CAM_PCLK_SRC_SEL_BMSK | + CAM_PCLK_INVERT_BMSK; + + value = 1 << CAM_SEL_SHFT | + 3 << CAM_PCLK_SRC_SEL_SHFT | + 0 << CAM_PCLK_INVERT_SHFT; + + writel((reg & (~mask)) | (value & mask), mdcbase); + mdelay(10); + + reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; + mask = CAM_PAD_REG_SW_RESET_BMSK; + value = 1 << CAM_PAD_REG_SW_RESET_SHFT; + writel((reg & (~mask)) | (value & mask), mdcbase); + mdelay(10); + + reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; + mask = CAM_PAD_REG_SW_RESET_BMSK; + value = 0 << CAM_PAD_REG_SW_RESET_SHFT; + writel((reg & (~mask)) | (value & mask), mdcbase); + mdelay(10); + + msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL); + mdelay(10); +} + +void msm_camio_vfe_blk_reset(void) +{ + uint32_t val; + + val = readl(appbase + 0x00000210); + val |= 0x1; + writel(val, appbase + 0x00000210); + mdelay(10); + + val = readl(appbase + 0x00000210); + val &= ~0x1; + writel(val, appbase + 0x00000210); + mdelay(10); +} + +void msm_camio_camif_pad_reg_reset_2(void) +{ + uint32_t reg; + uint32_t mask, value; + + reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; + mask = CAM_PAD_REG_SW_RESET_BMSK; + value = 1 << CAM_PAD_REG_SW_RESET_SHFT; + writel((reg & (~mask)) | (value & mask), mdcbase); + mdelay(10); + + reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; + mask = CAM_PAD_REG_SW_RESET_BMSK; + value = 0 << CAM_PAD_REG_SW_RESET_SHFT; + writel((reg & (~mask)) | (value & mask), mdcbase); + mdelay(10); +} + +void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype) +{ + struct clk *clk = NULL; + + clk = camio_vfe_clk; + + if (clk != NULL && clk != ERR_PTR(-ENOENT)) { + switch (srctype) { + case MSM_CAMIO_CLK_SRC_INTERNAL: + clk_set_flags(clk, 0x00000100 << 1); + break; + + case MSM_CAMIO_CLK_SRC_EXTERNAL: + clk_set_flags(clk, 0x00000100); + break; + + default: + break; + } + } +} + +int msm_camio_probe_on(struct platform_device *pdev) +{ + struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data; + struct msm_camera_device_platform_data *camdev = sinfo->pdata; + camdev->camera_gpio_on(); + return msm_camio_clk_enable(CAMIO_VFE_CLK); +} + +int msm_camio_probe_off(struct platform_device *pdev) +{ + struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data; + struct msm_camera_device_platform_data *camdev = sinfo->pdata; + camdev->camera_gpio_off(); + return msm_camio_clk_disable(CAMIO_VFE_CLK); +} diff --git a/trunk/drivers/staging/dream/camera/msm_io8x.c b/trunk/drivers/staging/dream/camera/msm_io8x.c new file mode 100644 index 000000000000..895161ae2e14 --- /dev/null +++ b/trunk/drivers/staging/dream/camera/msm_io8x.c @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2008-2009 QUALCOMM Incorporated + */ + +#include +#include +#include +#include +#include +#include + +#define CAMIF_CFG_RMSK 0x1fffff +#define CAM_SEL_BMSK 0x2 +#define CAM_PCLK_SRC_SEL_BMSK 0x60000 +#define CAM_PCLK_INVERT_BMSK 0x80000 +#define CAM_PAD_REG_SW_RESET_BMSK 0x100000 + +#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000 +#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000 +#define MDDI_CLK_CHICKEN_BIT_BMSK 0x80 + +#define CAM_SEL_SHFT 0x1 +#define CAM_PCLK_SRC_SEL_SHFT 0x11 +#define CAM_PCLK_INVERT_SHFT 0x13 +#define CAM_PAD_REG_SW_RESET_SHFT 0x14 + +#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10 +#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF +#define MDDI_CLK_CHICKEN_BIT_SHFT 0x7 +#define APPS_RESET_OFFSET 0x00000210 + +static struct clk *camio_vfe_mdc_clk; +static struct clk *camio_mdc_clk; +static struct clk *camio_vfe_clk; +static struct clk *camio_vfe_axi_clk; +static struct msm_camera_io_ext camio_ext; +static struct resource *appio, *mdcio; +void __iomem *appbase, *mdcbase; + +extern int clk_set_flags(struct clk *clk, unsigned long flags); + +int msm_camio_clk_enable(enum msm_camio_clk_type clktype) +{ + int rc = 0; + struct clk *clk = NULL; + + switch (clktype) { + case CAMIO_VFE_MDC_CLK: + camio_vfe_mdc_clk = + clk = clk_get(NULL, "vfe_mdc_clk"); + break; + + case CAMIO_MDC_CLK: + camio_mdc_clk = + clk = clk_get(NULL, "mdc_clk"); + break; + + case CAMIO_VFE_CLK: + camio_vfe_clk = + clk = clk_get(NULL, "vfe_clk"); + break; + + case CAMIO_VFE_AXI_CLK: + camio_vfe_axi_clk = + clk = clk_get(NULL, "vfe_axi_clk"); + break; + + default: + break; + } + + if (!IS_ERR(clk)) + clk_enable(clk); + else + rc = -1; + + return rc; +} + +int msm_camio_clk_disable(enum msm_camio_clk_type clktype) +{ + int rc = 0; + struct clk *clk = NULL; + + switch (clktype) { + case CAMIO_VFE_MDC_CLK: + clk = camio_vfe_mdc_clk; + break; + + case CAMIO_MDC_CLK: + clk = camio_mdc_clk; + break; + + case CAMIO_VFE_CLK: + clk = camio_vfe_clk; + break; + + case CAMIO_VFE_AXI_CLK: + clk = camio_vfe_axi_clk; + break; + + default: + break; + } + + if (!IS_ERR(clk)) { + clk_disable(clk); + clk_put(clk); + } else + rc = -1; + + return rc; +} + +void msm_camio_clk_rate_set(int rate) +{ + struct clk *clk = camio_vfe_mdc_clk; + + /* TODO: check return */ + clk_set_rate(clk, rate); +} + +int msm_camio_enable(struct platform_device *pdev) +{ + int rc = 0; + struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data; + struct msm_camera_device_platform_data *camdev = sinfo->pdata; + + camio_ext = camdev->ioext; + + appio = request_mem_region(camio_ext.appphy, + camio_ext.appsz, pdev->name); + if (!appio) { + rc = -EBUSY; + goto enable_fail; + } + + appbase = ioremap(camio_ext.appphy, + camio_ext.appsz); + if (!appbase) { + rc = -ENOMEM; + goto apps_no_mem; + } + + mdcio = request_mem_region(camio_ext.mdcphy, + camio_ext.mdcsz, pdev->name); + if (!mdcio) { + rc = -EBUSY; + goto mdc_busy; + } + + mdcbase = ioremap(camio_ext.mdcphy, + camio_ext.mdcsz); + if (!mdcbase) { + rc = -ENOMEM; + goto mdc_no_mem; + } + + camdev->camera_gpio_on(); + + msm_camio_clk_enable(CAMIO_VFE_CLK); + msm_camio_clk_enable(CAMIO_MDC_CLK); + msm_camio_clk_enable(CAMIO_VFE_MDC_CLK); + msm_camio_clk_enable(CAMIO_VFE_AXI_CLK); + return 0; + +mdc_no_mem: + release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz); +mdc_busy: + iounmap(appbase); +apps_no_mem: + release_mem_region(camio_ext.appphy, camio_ext.appsz); +enable_fail: + return rc; +} + +void msm_camio_disable(struct platform_device *pdev) +{ + struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data; + struct msm_camera_device_platform_data *camdev = sinfo->pdata; + + iounmap(mdcbase); + release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz); + iounmap(appbase); + release_mem_region(camio_ext.appphy, camio_ext.appsz); + + camdev->camera_gpio_off(); + + msm_camio_clk_disable(CAMIO_VFE_MDC_CLK); + msm_camio_clk_disable(CAMIO_MDC_CLK); + msm_camio_clk_disable(CAMIO_VFE_CLK); + msm_camio_clk_disable(CAMIO_VFE_AXI_CLK); +} + +void msm_camio_camif_pad_reg_reset(void) +{ + uint32_t reg; + uint32_t mask, value; + + /* select CLKRGM_VFE_SRC_CAM_VFE_SRC: internal source */ + msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL); + + reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; + + mask = CAM_SEL_BMSK | + CAM_PCLK_SRC_SEL_BMSK | + CAM_PCLK_INVERT_BMSK | + EXT_CAM_HSYNC_POL_SEL_BMSK | + EXT_CAM_VSYNC_POL_SEL_BMSK | + MDDI_CLK_CHICKEN_BIT_BMSK; + + value = 1 << CAM_SEL_SHFT | + 3 << CAM_PCLK_SRC_SEL_SHFT | + 0 << CAM_PCLK_INVERT_SHFT | + 0 << EXT_CAM_HSYNC_POL_SEL_SHFT | + 0 << EXT_CAM_VSYNC_POL_SEL_SHFT | + 0 << MDDI_CLK_CHICKEN_BIT_SHFT; + writel((reg & (~mask)) | (value & mask), mdcbase); + mdelay(10); + + reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; + mask = CAM_PAD_REG_SW_RESET_BMSK; + value = 1 << CAM_PAD_REG_SW_RESET_SHFT; + writel((reg & (~mask)) | (value & mask), mdcbase); + mdelay(10); + + reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; + mask = CAM_PAD_REG_SW_RESET_BMSK; + value = 0 << CAM_PAD_REG_SW_RESET_SHFT; + writel((reg & (~mask)) | (value & mask), mdcbase); + mdelay(10); + + msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL); + + mdelay(10); + + /* todo: check return */ + if (camio_vfe_clk) + clk_set_rate(camio_vfe_clk, 96000000); +} + +void msm_camio_vfe_blk_reset(void) +{ + uint32_t val; + + val = readl(appbase + 0x00000210); + val |= 0x1; + writel(val, appbase + 0x00000210); + mdelay(10); + + val = readl(appbase + 0x00000210); + val &= ~0x1; + writel(val, appbase + 0x00000210); + mdelay(10); +} + +void msm_camio_camif_pad_reg_reset_2(void) +{ + uint32_t reg; + uint32_t mask, value; + + reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; + mask = CAM_PAD_REG_SW_RESET_BMSK; + value = 1 << CAM_PAD_REG_SW_RESET_SHFT; + writel((reg & (~mask)) | (value & mask), mdcbase); + mdelay(10); + + reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; + mask = CAM_PAD_REG_SW_RESET_BMSK; + value = 0 << CAM_PAD_REG_SW_RESET_SHFT; + writel((reg & (~mask)) | (value & mask), mdcbase); + mdelay(10); +} + +void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype) +{ + struct clk *clk = NULL; + + clk = camio_vfe_clk; + + if (clk != NULL) { + switch (srctype) { + case MSM_CAMIO_CLK_SRC_INTERNAL: + clk_set_flags(clk, 0x00000100 << 1); + break; + + case MSM_CAMIO_CLK_SRC_EXTERNAL: + clk_set_flags(clk, 0x00000100); + break; + + default: + break; + } + } +} + +void msm_camio_clk_axi_rate_set(int rate) +{ + struct clk *clk = camio_vfe_axi_clk; + /* todo: check return */ + clk_set_rate(clk, rate); +} + +int msm_camio_probe_on(struct platform_device *pdev) +{ + struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data; + struct msm_camera_device_platform_data *camdev = sinfo->pdata; + + camdev->camera_gpio_on(); + return msm_camio_clk_enable(CAMIO_VFE_MDC_CLK); +} + +int msm_camio_probe_off(struct platform_device *pdev) +{ + struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data; + struct msm_camera_device_platform_data *camdev = sinfo->pdata; + + camdev->camera_gpio_off(); + return msm_camio_clk_disable(CAMIO_VFE_MDC_CLK); +} diff --git a/trunk/drivers/staging/dream/camera/msm_v4l2.c b/trunk/drivers/staging/dream/camera/msm_v4l2.c new file mode 100644 index 000000000000..c276f2f7583a --- /dev/null +++ b/trunk/drivers/staging/dream/camera/msm_v4l2.c @@ -0,0 +1,798 @@ +/* + * + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/*#include */ + +#define MSM_V4L2_START_SNAPSHOT _IOWR('V', BASE_VIDIOC_PRIVATE+1, \ + struct v4l2_buffer) + +#define MSM_V4L2_GET_PICTURE _IOWR('V', BASE_VIDIOC_PRIVATE+2, \ + struct v4l2_buffer) + +#define MSM_V4L2_DEVICE_NAME "msm_v4l2" + +#define MSM_V4L2_PROC_NAME "msm_v4l2" + +#define MSM_V4L2_DEVNUM_MPEG2 0 +#define MSM_V4L2_DEVNUM_YUV 20 + +/* HVGA-P (portrait) and HVGA-L (landscape) */ +#define MSM_V4L2_WIDTH 480 +#define MSM_V4L2_HEIGHT 320 + +#if 1 +#define D(fmt, args...) printk(KERN_INFO "msm_v4l2: " fmt, ##args) +#else +#define D(fmt, args...) do {} while (0) +#endif + +#define PREVIEW_FRAMES_NUM 4 + +struct msm_v4l2_device { + struct list_head read_queue; + struct v4l2_format current_cap_format; + struct v4l2_format current_pix_format; + struct video_device *pvdev; + struct msm_v4l2_driver *drv; + uint8_t opencnt; + + spinlock_t read_queue_lock; +}; + +static struct msm_v4l2_device *g_pmsm_v4l2_dev; + + +static DEFINE_MUTEX(msm_v4l2_opencnt_lock); + +static int msm_v4l2_open(struct file *f) +{ + int rc = 0; + D("%s\n", __func__); + mutex_lock(&msm_v4l2_opencnt_lock); + if (!g_pmsm_v4l2_dev->opencnt) { + rc = g_pmsm_v4l2_dev->drv->open( + g_pmsm_v4l2_dev->drv->sync, + MSM_APPS_ID_V4L2); + } + g_pmsm_v4l2_dev->opencnt++; + mutex_unlock(&msm_v4l2_opencnt_lock); + return rc; +} + +static int msm_v4l2_release(struct file *f) +{ + int rc = 0; + D("%s\n", __func__); + mutex_lock(&msm_v4l2_opencnt_lock); + if (!g_pmsm_v4l2_dev->opencnt) { + g_pmsm_v4l2_dev->opencnt--; + if (!g_pmsm_v4l2_dev->opencnt) { + rc = g_pmsm_v4l2_dev->drv->release( + g_pmsm_v4l2_dev->drv->sync); + } + } + mutex_unlock(&msm_v4l2_opencnt_lock); + return rc; +} + +static unsigned int msm_v4l2_poll(struct file *f, struct poll_table_struct *w) +{ + return g_pmsm_v4l2_dev->drv->drv_poll(g_pmsm_v4l2_dev->drv->sync, f, w); +} + +static long msm_v4l2_ioctl(struct file *filep, + unsigned int cmd, unsigned long arg) +{ + struct msm_ctrl_cmd *ctrlcmd; + + D("msm_v4l2_ioctl, cmd = %d, %d\n", cmd, __LINE__); + + switch (cmd) { + case MSM_V4L2_START_SNAPSHOT: + + ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC); + if (!ctrlcmd) { + CDBG("msm_v4l2_ioctl: cannot allocate buffer\n"); + return -ENOMEM; + } + + ctrlcmd->length = 0; + ctrlcmd->value = NULL; + ctrlcmd->timeout_ms = 10000; + + D("msm_v4l2_ioctl, MSM_V4L2_START_SNAPSHOT v4l2 ioctl %d\n", + cmd); + ctrlcmd->type = MSM_V4L2_SNAPSHOT; + return g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, + ctrlcmd); + + case MSM_V4L2_GET_PICTURE: + D("msm_v4l2_ioctl, MSM_V4L2_GET_PICTURE v4l2 ioctl %d\n", cmd); + ctrlcmd = (struct msm_ctrl_cmd *)arg; + return g_pmsm_v4l2_dev->drv->get_pict( + g_pmsm_v4l2_dev->drv->sync, ctrlcmd); + + default: + D("msm_v4l2_ioctl, standard v4l2 ioctl %d\n", cmd); + return video_ioctl2(filep, cmd, arg); + } +} + +static void msm_v4l2_release_dev(struct video_device *d) +{ + D("%s\n", __func__); +} + +static int msm_v4l2_querycap(struct file *f, + void *pctx, struct v4l2_capability *pcaps) +{ + D("%s\n", __func__); + strncpy(pcaps->driver, MSM_APPS_ID_V4L2, sizeof(pcaps->driver)); + strncpy(pcaps->card, + MSM_V4L2_DEVICE_NAME, sizeof(pcaps->card)); + pcaps->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + return 0; +} + +static int msm_v4l2_s_std(struct file *f, void *pctx, v4l2_std_id *pnorm) +{ + D("%s\n", __func__); + return 0; +} + +static int msm_v4l2_queryctrl(struct file *f, + void *pctx, struct v4l2_queryctrl *pqctrl) +{ + int rc = 0; + struct msm_ctrl_cmd *ctrlcmd; + + D("%s\n", __func__); + + ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC); + if (!ctrlcmd) { + CDBG("msm_v4l2_queryctrl: cannot allocate buffer\n"); + return -ENOMEM; + } + + ctrlcmd->type = MSM_V4L2_QUERY_CTRL; + ctrlcmd->length = sizeof(struct v4l2_queryctrl); + ctrlcmd->value = pqctrl; + ctrlcmd->timeout_ms = 10000; + + rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd); + if (rc < 0) + return -1; + + return ctrlcmd->status; +} + +static int msm_v4l2_g_ctrl(struct file *f, void *pctx, struct v4l2_control *c) +{ + int rc = 0; + struct msm_ctrl_cmd *ctrlcmd; + + D("%s\n", __func__); + + ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC); + if (!ctrlcmd) { + CDBG("msm_v4l2_g_ctrl: cannot allocate buffer\n"); + return -ENOMEM; + } + + ctrlcmd->type = MSM_V4L2_GET_CTRL; + ctrlcmd->length = sizeof(struct v4l2_control); + ctrlcmd->value = c; + ctrlcmd->timeout_ms = 10000; + + rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd); + if (rc < 0) + return -1; + + return ctrlcmd->status; +} + +static int msm_v4l2_s_ctrl(struct file *f, void *pctx, struct v4l2_control *c) +{ + int rc = 0; + struct msm_ctrl_cmd *ctrlcmd; + + ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC); + if (!ctrlcmd) { + CDBG("msm_v4l2_s_ctrl: cannot allocate buffer\n"); + return -ENOMEM; + } + + ctrlcmd->type = MSM_V4L2_SET_CTRL; + ctrlcmd->length = sizeof(struct v4l2_control); + ctrlcmd->value = c; + ctrlcmd->timeout_ms = 10000; + + D("%s\n", __func__); + + rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd); + if (rc < 0) + return -1; + + return ctrlcmd->status; +} + +static int msm_v4l2_reqbufs(struct file *f, + void *pctx, struct v4l2_requestbuffers *b) +{ + D("%s\n", __func__); + return 0; +} + +static int msm_v4l2_querybuf(struct file *f, void *pctx, struct v4l2_buffer *pb) +{ + struct msm_pmem_info pmem_buf; +#if 0 + __u32 width = 0; + __u32 height = 0; + __u32 y_size = 0; + __u32 y_pad = 0; + + /* FIXME: g_pmsm_v4l2_dev->current_pix_format.fmt.pix.width; */ + width = 640; + /* FIXME: g_pmsm_v4l2_dev->current_pix_format.fmt.pix.height; */ + height = 480; + + D("%s: width = %d, height = %d\n", __func__, width, height); + + y_size = width * height; + y_pad = y_size % 4; +#endif + + __u32 y_pad = pb->bytesused % 4; + + /* V4L2 videodev will do the copy_from_user. */ + + memset(&pmem_buf, 0, sizeof(struct msm_pmem_info)); + pmem_buf.type = MSM_PMEM_OUTPUT2; + pmem_buf.vaddr = (void *)pb->m.userptr; + pmem_buf.y_off = 0; + pmem_buf.fd = (int)pb->reserved; + /* pmem_buf.cbcr_off = (y_size + y_pad); */ + pmem_buf.cbcr_off = (pb->bytesused + y_pad); + + g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync, &pmem_buf); + + return 0; +} + +static int msm_v4l2_qbuf(struct file *f, void *pctx, struct v4l2_buffer *pb) +{ + /* + __u32 y_size = 0; + __u32 y_pad = 0; + __u32 width = 0; + __u32 height = 0; + */ + + __u32 y_pad = 0; + + struct msm_pmem_info meminfo; + struct msm_frame frame; + static int cnt; + + if ((pb->flags >> 16) & 0x0001) { + /* this is for previwe */ +#if 0 + width = 640; + height = 480; + + /* V4L2 videodev will do the copy_from_user. */ + D("%s: width = %d, height = %d\n", __func__, width, height); + y_size = width * height; + y_pad = y_size % 4; +#endif + + y_pad = pb->bytesused % 4; + + if (pb->type == V4L2_BUF_TYPE_PRIVATE) { + /* this qbuf is actually for releasing */ + + frame.buffer = pb->m.userptr; + frame.y_off = 0; + /* frame.cbcr_off = (y_size + y_pad); */ + frame.cbcr_off = (pb->bytesused + y_pad); + frame.fd = pb->reserved; + + D("V4L2_BUF_TYPE_PRIVATE: pb->bytesused = %d \n", + pb->bytesused); + + g_pmsm_v4l2_dev->drv->put_frame( + g_pmsm_v4l2_dev->drv->sync, + &frame); + + return 0; + } + + D("V4L2_BUF_TYPE_VIDEO_CAPTURE: pb->bytesused = %d \n", + pb->bytesused); + + meminfo.type = MSM_PMEM_OUTPUT2; + meminfo.fd = (int)pb->reserved; + meminfo.vaddr = (void *)pb->m.userptr; + meminfo.y_off = 0; + /* meminfo.cbcr_off = (y_size + y_pad); */ + meminfo.cbcr_off = (pb->bytesused + y_pad); + if (cnt == PREVIEW_FRAMES_NUM - 1) + meminfo.active = 0; + else + meminfo.active = 1; + cnt++; + g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync, + &meminfo); + } else if ((pb->flags) & 0x0001) { + /* this is for snapshot */ + + __u32 y_size = 0; + + if ((pb->flags >> 8) & 0x01) { + + y_size = pb->bytesused; + + meminfo.type = MSM_PMEM_THUMBAIL; + } else if ((pb->flags >> 9) & 0x01) { + + y_size = pb->bytesused; + + meminfo.type = MSM_PMEM_MAINIMG; + } + + y_pad = y_size % 4; + + meminfo.fd = (int)pb->reserved; + meminfo.vaddr = (void *)pb->m.userptr; + meminfo.y_off = 0; + /* meminfo.cbcr_off = (y_size + y_pad); */ + meminfo.cbcr_off = (y_size + y_pad); + meminfo.active = 1; + g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync, + &meminfo); + } + + return 0; +} + +static int msm_v4l2_dqbuf(struct file *f, void *pctx, struct v4l2_buffer *pb) +{ + struct msm_frame frame; + D("%s\n", __func__); + + /* V4L2 videodev will do the copy_to_user. */ + if (pb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { + + D("%s, %d\n", __func__, __LINE__); + + g_pmsm_v4l2_dev->drv->get_frame( + g_pmsm_v4l2_dev->drv->sync, + &frame); + + pb->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + pb->m.userptr = (unsigned long)frame.buffer; /* FIXME */ + pb->reserved = (int)frame.fd; + /* pb->length = (int)frame.cbcr_off; */ + + pb->bytesused = frame.cbcr_off; + + } else if (pb->type == V4L2_BUF_TYPE_PRIVATE) { + __u32 y_pad = pb->bytesused % 4; + + frame.buffer = pb->m.userptr; + frame.y_off = 0; + /* frame.cbcr_off = (y_size + y_pad); */ + frame.cbcr_off = (pb->bytesused + y_pad); + frame.fd = pb->reserved; + + g_pmsm_v4l2_dev->drv->put_frame( + g_pmsm_v4l2_dev->drv->sync, + &frame); + } + + return 0; +} + +static int msm_v4l2_streamon(struct file *f, void *pctx, enum v4l2_buf_type i) +{ + struct msm_ctrl_cmd *ctrlcmd; + + ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC); + if (!ctrlcmd) { + CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n"); + return -ENOMEM; + } + + ctrlcmd->type = MSM_V4L2_STREAM_ON; + ctrlcmd->timeout_ms = 10000; + ctrlcmd->length = 0; + ctrlcmd->value = NULL; + + D("%s\n", __func__); + + g_pmsm_v4l2_dev->drv->ctrl( + g_pmsm_v4l2_dev->drv->sync, + ctrlcmd); + + D("%s after drv->ctrl \n", __func__); + + return 0; +} + +static int msm_v4l2_streamoff(struct file *f, void *pctx, enum v4l2_buf_type i) +{ + struct msm_ctrl_cmd *ctrlcmd; + + ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC); + if (!ctrlcmd) { + CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n"); + return -ENOMEM; + } + + ctrlcmd->type = MSM_V4L2_STREAM_OFF; + ctrlcmd->timeout_ms = 10000; + ctrlcmd->length = 0; + ctrlcmd->value = NULL; + + + D("%s\n", __func__); + + g_pmsm_v4l2_dev->drv->ctrl( + g_pmsm_v4l2_dev->drv->sync, + ctrlcmd); + + return 0; +} + +static int msm_v4l2_enum_fmt_overlay(struct file *f, + void *pctx, struct v4l2_fmtdesc *pfmtdesc) +{ + D("%s\n", __func__); + return 0; +} + +static int msm_v4l2_enum_fmt_cap(struct file *f, + void *pctx, struct v4l2_fmtdesc *pfmtdesc) +{ + D("%s\n", __func__); + + switch (pfmtdesc->index) { + case 0: + pfmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + pfmtdesc->flags = 0; + strncpy(pfmtdesc->description, "YUV 4:2:0", + sizeof(pfmtdesc->description)); + pfmtdesc->pixelformat = V4L2_PIX_FMT_YVU420; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int msm_v4l2_g_fmt_cap(struct file *f, + void *pctx, struct v4l2_format *pfmt) +{ + D("%s\n", __func__); + pfmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + pfmt->fmt.pix.width = MSM_V4L2_WIDTH; + pfmt->fmt.pix.height = MSM_V4L2_HEIGHT; + pfmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420; + pfmt->fmt.pix.field = V4L2_FIELD_ANY; + pfmt->fmt.pix.bytesperline = 0; + pfmt->fmt.pix.sizeimage = 0; + pfmt->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; + pfmt->fmt.pix.priv = 0; + return 0; +} + +static int msm_v4l2_s_fmt_cap(struct file *f, + void *pctx, struct v4l2_format *pfmt) +{ + struct msm_ctrl_cmd *ctrlcmd; + + D("%s\n", __func__); + + ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC); + if (!ctrlcmd) { + CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n"); + return -ENOMEM; + } + + ctrlcmd->type = MSM_V4L2_VID_CAP_TYPE; + ctrlcmd->length = sizeof(struct v4l2_format); + ctrlcmd->value = pfmt; + ctrlcmd->timeout_ms = 10000; + + if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + kfree(ctrlcmd); + return -1; + } + +#if 0 + /* FIXEME */ + if (pfmt->fmt.pix.pixelformat != V4L2_PIX_FMT_YVU420) { + kfree(ctrlcmd); + return -EINVAL; + } +#endif + + /* Ok, but check other params, too. */ + +#if 0 + memcpy(&g_pmsm_v4l2_dev->current_pix_format.fmt.pix, pfmt, + sizeof(struct v4l2_format)); +#endif + + g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd); + + return 0; +} + +static int msm_v4l2_g_fmt_overlay(struct file *f, + void *pctx, struct v4l2_format *pfmt) +{ + D("%s\n", __func__); + pfmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + pfmt->fmt.pix.width = MSM_V4L2_WIDTH; + pfmt->fmt.pix.height = MSM_V4L2_HEIGHT; + pfmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420; + pfmt->fmt.pix.field = V4L2_FIELD_ANY; + pfmt->fmt.pix.bytesperline = 0; + pfmt->fmt.pix.sizeimage = 0; + pfmt->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; + pfmt->fmt.pix.priv = 0; + return 0; +} + +static int msm_v4l2_s_fmt_overlay(struct file *f, + void *pctx, struct v4l2_format *pfmt) +{ + D("%s\n", __func__); + return 0; +} + +static int msm_v4l2_overlay(struct file *f, void *pctx, unsigned int i) +{ + D("%s\n", __func__); + return 0; +} + +static int msm_v4l2_g_jpegcomp(struct file *f, + void *pctx, struct v4l2_jpegcompression *pcomp) +{ + D("%s\n", __func__); + return 0; +} + +static int msm_v4l2_s_jpegcomp(struct file *f, + void *pctx, struct v4l2_jpegcompression *pcomp) +{ + D("%s\n", __func__); + return 0; +} + +#ifdef CONFIG_PROC_FS +int msm_v4l2_read_proc(char *pbuf, char **start, off_t offset, + int count, int *eof, void *data) +{ + int len = 0; + len += snprintf(pbuf, strlen("stats\n") + 1, "stats\n"); + + if (g_pmsm_v4l2_dev) { + len += snprintf(pbuf, strlen("mode: ") + 1, "mode: "); + + if (g_pmsm_v4l2_dev->current_cap_format.type + == V4L2_BUF_TYPE_VIDEO_CAPTURE) + len += snprintf(pbuf, strlen("capture\n") + 1, + "capture\n"); + else + len += snprintf(pbuf, strlen("unknown\n") + 1, + "unknown\n"); + + len += snprintf(pbuf, 21, "resolution: %dx%d\n", + g_pmsm_v4l2_dev->current_cap_format.fmt.pix. + width, + g_pmsm_v4l2_dev->current_cap_format.fmt.pix. + height); + + len += snprintf(pbuf, + strlen("pixel format: ") + 1, "pixel format: "); + if (g_pmsm_v4l2_dev->current_cap_format.fmt.pix.pixelformat + == V4L2_PIX_FMT_YVU420) + len += snprintf(pbuf, strlen("yvu420\n") + 1, + "yvu420\n"); + else + len += snprintf(pbuf, strlen("unknown\n") + 1, + "unknown\n"); + + len += snprintf(pbuf, strlen("colorspace: ") + 1, + "colorspace: "); + if (g_pmsm_v4l2_dev->current_cap_format.fmt.pix.colorspace + == V4L2_COLORSPACE_JPEG) + len += snprintf(pbuf, strlen("jpeg\n") + 1, "jpeg\n"); + else + len += snprintf(pbuf, strlen("unknown\n") + 1, + "unknown\n"); + } + + *eof = 1; + return len; +} +#endif + +static const struct v4l2_file_operations msm_v4l2_fops = { + .owner = THIS_MODULE, + .open = msm_v4l2_open, + .poll = msm_v4l2_poll, + .release = msm_v4l2_release, + .ioctl = msm_v4l2_ioctl, +}; + +static void msm_v4l2_dev_init(struct msm_v4l2_device *pmsm_v4l2_dev) +{ + pmsm_v4l2_dev->read_queue_lock = + __SPIN_LOCK_UNLOCKED(pmsm_v4l2_dev->read_queue_lock); + INIT_LIST_HEAD(&pmsm_v4l2_dev->read_queue); +} + +static int msm_v4l2_try_fmt_cap(struct file *file, + void *fh, struct v4l2_format *f) +{ + /* FIXME */ + return 0; +} + +static int mm_v4l2_try_fmt_type_private(struct file *file, + void *fh, struct v4l2_format *f) +{ + /* FIXME */ + return 0; +} + +/* + * should the following structure be used instead of the code in the function? + * static const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = { + * .vidioc_querycap = .... + * } + */ +static const struct v4l2_ioctl_ops msm_ioctl_ops = { + .vidioc_querycap = msm_v4l2_querycap, + .vidioc_s_std = msm_v4l2_s_std, + + .vidioc_queryctrl = msm_v4l2_queryctrl, + .vidioc_g_ctrl = msm_v4l2_g_ctrl, + .vidioc_s_ctrl = msm_v4l2_s_ctrl, + + .vidioc_reqbufs = msm_v4l2_reqbufs, + .vidioc_querybuf = msm_v4l2_querybuf, + .vidioc_qbuf = msm_v4l2_qbuf, + .vidioc_dqbuf = msm_v4l2_dqbuf, + + .vidioc_streamon = msm_v4l2_streamon, + .vidioc_streamoff = msm_v4l2_streamoff, + + .vidioc_enum_fmt_vid_overlay = msm_v4l2_enum_fmt_overlay, + .vidioc_enum_fmt_vid_cap = msm_v4l2_enum_fmt_cap, + + .vidioc_try_fmt_vid_cap = msm_v4l2_try_fmt_cap, + .vidioc_try_fmt_type_private = mm_v4l2_try_fmt_type_private, + + .vidioc_g_fmt_vid_cap = msm_v4l2_g_fmt_cap, + .vidioc_s_fmt_vid_cap = msm_v4l2_s_fmt_cap, + .vidioc_g_fmt_vid_overlay = msm_v4l2_g_fmt_overlay, + .vidioc_s_fmt_vid_overlay = msm_v4l2_s_fmt_overlay, + .vidioc_overlay = msm_v4l2_overlay, + + .vidioc_g_jpegcomp = msm_v4l2_g_jpegcomp, + .vidioc_s_jpegcomp = msm_v4l2_s_jpegcomp, +}; + +static int msm_v4l2_video_dev_init(struct video_device *pvd) +{ + strncpy(pvd->name, MSM_APPS_ID_V4L2, sizeof(pvd->name)); + pvd->vfl_type = 1; + pvd->fops = &msm_v4l2_fops; + pvd->release = msm_v4l2_release_dev; + pvd->minor = -1; + pvd->ioctl_ops = &msm_ioctl_ops; + return msm_v4l2_register(g_pmsm_v4l2_dev->drv); +} + +static int __init msm_v4l2_init(void) +{ + int rc = -ENOMEM; + struct video_device *pvdev = NULL; + struct msm_v4l2_device *pmsm_v4l2_dev = NULL; + D("%s\n", __func__); + + pvdev = video_device_alloc(); + if (pvdev == NULL) + return rc; + + pmsm_v4l2_dev = + kzalloc(sizeof(struct msm_v4l2_device), GFP_KERNEL); + if (pmsm_v4l2_dev == NULL) { + video_device_release(pvdev); + return rc; + } + + msm_v4l2_dev_init(pmsm_v4l2_dev); + + g_pmsm_v4l2_dev = pmsm_v4l2_dev; + g_pmsm_v4l2_dev->pvdev = pvdev; + + g_pmsm_v4l2_dev->drv = + kzalloc(sizeof(struct msm_v4l2_driver), GFP_KERNEL); + if (!g_pmsm_v4l2_dev->drv) { + video_device_release(pvdev); + kfree(pmsm_v4l2_dev); + return rc; + } + + rc = msm_v4l2_video_dev_init(pvdev); + if (rc < 0) { + video_device_release(pvdev); + kfree(g_pmsm_v4l2_dev->drv); + kfree(pmsm_v4l2_dev); + return rc; + } + + if (video_register_device(pvdev, VFL_TYPE_GRABBER, + MSM_V4L2_DEVNUM_YUV)) { + D("failed to register device\n"); + video_device_release(pvdev); + kfree(g_pmsm_v4l2_dev); + g_pmsm_v4l2_dev = NULL; + return -ENOENT; + } +#ifdef CONFIG_PROC_FS + create_proc_read_entry(MSM_V4L2_PROC_NAME, + 0, NULL, msm_v4l2_read_proc, NULL); +#endif + + return 0; +} + +static void __exit msm_v4l2_exit(void) +{ + struct video_device *pvdev = g_pmsm_v4l2_dev->pvdev; + D("%s\n", __func__); +#ifdef CONFIG_PROC_FS + remove_proc_entry(MSM_V4L2_PROC_NAME, NULL); +#endif + video_unregister_device(pvdev); + video_device_release(pvdev); + + msm_v4l2_unregister(g_pmsm_v4l2_dev->drv); + + kfree(g_pmsm_v4l2_dev->drv); + g_pmsm_v4l2_dev->drv = NULL; + + kfree(g_pmsm_v4l2_dev); + g_pmsm_v4l2_dev = NULL; +} + +module_init(msm_v4l2_init); +module_exit(msm_v4l2_exit); + +MODULE_DESCRIPTION("MSM V4L2 driver"); +MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/staging/dream/camera/msm_vfe7x.c b/trunk/drivers/staging/dream/camera/msm_vfe7x.c new file mode 100644 index 000000000000..198656ac3de5 --- /dev/null +++ b/trunk/drivers/staging/dream/camera/msm_vfe7x.c @@ -0,0 +1,702 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm_vfe7x.h" + +#define QDSP_CMDQUEUE QDSP_vfeCommandQueue + +#define VFE_RESET_CMD 0 +#define VFE_START_CMD 1 +#define VFE_STOP_CMD 2 +#define VFE_FRAME_ACK 20 +#define STATS_AF_ACK 21 +#define STATS_WE_ACK 22 + +#define MSG_STOP_ACK 1 +#define MSG_SNAPSHOT 2 +#define MSG_OUTPUT1 6 +#define MSG_OUTPUT2 7 +#define MSG_STATS_AF 8 +#define MSG_STATS_WE 9 + +static struct msm_adsp_module *qcam_mod; +static struct msm_adsp_module *vfe_mod; +static struct msm_vfe_callback *resp; +static void *extdata; +static uint32_t extlen; + +struct mutex vfe_lock; +static void *vfe_syncdata; +static uint8_t vfestopped; + +static struct stop_event stopevent; + +static void vfe_7x_convert(struct msm_vfe_phy_info *pinfo, + enum vfe_resp_msg type, + void *data, void **ext, int32_t *elen) +{ + switch (type) { + case VFE_MSG_OUTPUT1: + case VFE_MSG_OUTPUT2: { + pinfo->y_phy = ((struct vfe_endframe *)data)->y_address; + pinfo->cbcr_phy = + ((struct vfe_endframe *)data)->cbcr_address; + + CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n", + pinfo->y_phy, pinfo->cbcr_phy); + + ((struct vfe_frame_extra *)extdata)->bl_evencol = + ((struct vfe_endframe *)data)->blacklevelevencolumn; + + ((struct vfe_frame_extra *)extdata)->bl_oddcol = + ((struct vfe_endframe *)data)->blackleveloddcolumn; + + ((struct vfe_frame_extra *)extdata)->g_def_p_cnt = + ((struct vfe_endframe *)data)->greendefectpixelcount; + + ((struct vfe_frame_extra *)extdata)->r_b_def_p_cnt = + ((struct vfe_endframe *)data)->redbluedefectpixelcount; + + *ext = extdata; + *elen = extlen; + } + break; + + case VFE_MSG_STATS_AF: + case VFE_MSG_STATS_WE: + pinfo->sbuf_phy = *(uint32_t *)data; + break; + + default: + break; + } /* switch */ +} + +static void vfe_7x_ops(void *driver_data, unsigned id, size_t len, + void (*getevent)(void *ptr, size_t len)) +{ + uint32_t evt_buf[3]; + struct msm_vfe_resp *rp; + void *data; + + len = (id == (uint16_t)-1) ? 0 : len; + data = resp->vfe_alloc(sizeof(struct msm_vfe_resp) + len, vfe_syncdata); + + if (!data) { + pr_err("rp: cannot allocate buffer\n"); + return; + } + rp = (struct msm_vfe_resp *)data; + rp->evt_msg.len = len; + + if (id == ((uint16_t)-1)) { + /* event */ + rp->type = VFE_EVENT; + rp->evt_msg.type = MSM_CAMERA_EVT; + getevent(evt_buf, sizeof(evt_buf)); + rp->evt_msg.msg_id = evt_buf[0]; + resp->vfe_resp(rp, MSM_CAM_Q_VFE_EVT, vfe_syncdata); + } else { + /* messages */ + rp->evt_msg.type = MSM_CAMERA_MSG; + rp->evt_msg.msg_id = id; + rp->evt_msg.data = rp + 1; + getevent(rp->evt_msg.data, len); + + switch (rp->evt_msg.msg_id) { + case MSG_SNAPSHOT: + rp->type = VFE_MSG_SNAPSHOT; + break; + + case MSG_OUTPUT1: + rp->type = VFE_MSG_OUTPUT1; + vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT1, + rp->evt_msg.data, &(rp->extdata), + &(rp->extlen)); + break; + + case MSG_OUTPUT2: + rp->type = VFE_MSG_OUTPUT2; + vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT2, + rp->evt_msg.data, &(rp->extdata), + &(rp->extlen)); + break; + + case MSG_STATS_AF: + rp->type = VFE_MSG_STATS_AF; + vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_AF, + rp->evt_msg.data, NULL, NULL); + break; + + case MSG_STATS_WE: + rp->type = VFE_MSG_STATS_WE; + vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_WE, + rp->evt_msg.data, NULL, NULL); + + CDBG("MSG_STATS_WE: phy = 0x%x\n", rp->phy.sbuf_phy); + break; + + case MSG_STOP_ACK: + rp->type = VFE_MSG_GENERAL; + stopevent.state = 1; + wake_up(&stopevent.wait); + break; + + + default: + rp->type = VFE_MSG_GENERAL; + break; + } + resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG, vfe_syncdata); + } +} + +static struct msm_adsp_ops vfe_7x_sync = { + .event = vfe_7x_ops, +}; + +static int vfe_7x_enable(struct camera_enable_cmd *enable) +{ + int rc = -EFAULT; + + if (!strcmp(enable->name, "QCAMTASK")) + rc = msm_adsp_enable(qcam_mod); + else if (!strcmp(enable->name, "VFETASK")) + rc = msm_adsp_enable(vfe_mod); + + return rc; +} + +static int vfe_7x_disable(struct camera_enable_cmd *enable, + struct platform_device *dev __attribute__((unused))) +{ + int rc = -EFAULT; + + if (!strcmp(enable->name, "QCAMTASK")) + rc = msm_adsp_disable(qcam_mod); + else if (!strcmp(enable->name, "VFETASK")) + rc = msm_adsp_disable(vfe_mod); + + return rc; +} + +static int vfe_7x_stop(void) +{ + int rc = 0; + uint32_t stopcmd = VFE_STOP_CMD; + rc = msm_adsp_write(vfe_mod, QDSP_CMDQUEUE, + &stopcmd, sizeof(uint32_t)); + if (rc < 0) { + CDBG("%s:%d: failed rc = %d \n", __func__, __LINE__, rc); + return rc; + } + + stopevent.state = 0; + rc = wait_event_timeout(stopevent.wait, + stopevent.state != 0, + msecs_to_jiffies(stopevent.timeout)); + + return rc; +} + +static void vfe_7x_release(struct platform_device *pdev) +{ + mutex_lock(&vfe_lock); + vfe_syncdata = NULL; + mutex_unlock(&vfe_lock); + + if (!vfestopped) { + CDBG("%s:%d:Calling vfe_7x_stop()\n", __func__, __LINE__); + vfe_7x_stop(); + } else + vfestopped = 0; + + msm_adsp_disable(qcam_mod); + msm_adsp_disable(vfe_mod); + + msm_adsp_put(qcam_mod); + msm_adsp_put(vfe_mod); + + msm_camio_disable(pdev); + + kfree(extdata); + extlen = 0; +} + +static int vfe_7x_init(struct msm_vfe_callback *presp, + struct platform_device *dev) +{ + int rc = 0; + + init_waitqueue_head(&stopevent.wait); + stopevent.timeout = 200; + stopevent.state = 0; + + if (presp && presp->vfe_resp) + resp = presp; + else + return -EFAULT; + + /* Bring up all the required GPIOs and Clocks */ + rc = msm_camio_enable(dev); + if (rc < 0) + return rc; + + msm_camio_camif_pad_reg_reset(); + + extlen = sizeof(struct vfe_frame_extra); + + extdata = kmalloc(extlen, GFP_ATOMIC); + if (!extdata) { + rc = -ENOMEM; + goto init_fail; + } + + rc = msm_adsp_get("QCAMTASK", &qcam_mod, &vfe_7x_sync, NULL); + if (rc) { + rc = -EBUSY; + goto get_qcam_fail; + } + + rc = msm_adsp_get("VFETASK", &vfe_mod, &vfe_7x_sync, NULL); + if (rc) { + rc = -EBUSY; + goto get_vfe_fail; + } + + return 0; + +get_vfe_fail: + msm_adsp_put(qcam_mod); +get_qcam_fail: + kfree(extdata); +init_fail: + extlen = 0; + return rc; +} + +static int vfe_7x_config_axi(int mode, + struct axidata *ad, struct axiout *ao) +{ + struct msm_pmem_region *regptr; + unsigned long *bptr; + int cnt; + + int rc = 0; + + if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) { + regptr = ad->region; + + CDBG("bufnum1 = %d\n", ad->bufnum1); + CDBG("config_axi1: O1, phy = 0x%lx, y_off = %d, cbcr_off =%d\n", + regptr->paddr, regptr->y_off, regptr->cbcr_off); + + bptr = &ao->output1buffer1_y_phy; + for (cnt = 0; cnt < ad->bufnum1; cnt++) { + *bptr = regptr->paddr + regptr->y_off; + bptr++; + *bptr = regptr->paddr + regptr->cbcr_off; + + bptr++; + regptr++; + } + + regptr--; + for (cnt = 0; cnt < (8 - ad->bufnum1); cnt++) { + *bptr = regptr->paddr + regptr->y_off; + bptr++; + *bptr = regptr->paddr + regptr->cbcr_off; + bptr++; + } + } /* if OUTPUT1 or Both */ + + if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) { + regptr = &(ad->region[ad->bufnum1]); + + CDBG("bufnum2 = %d\n", ad->bufnum2); + CDBG("config_axi2: O2, phy = 0x%lx, y_off = %d, cbcr_off =%d\n", + regptr->paddr, regptr->y_off, regptr->cbcr_off); + + bptr = &ao->output2buffer1_y_phy; + for (cnt = 0; cnt < ad->bufnum2; cnt++) { + *bptr = regptr->paddr + regptr->y_off; + bptr++; + *bptr = regptr->paddr + regptr->cbcr_off; + + bptr++; + regptr++; + } + + regptr--; + for (cnt = 0; cnt < (8 - ad->bufnum2); cnt++) { + *bptr = regptr->paddr + regptr->y_off; + bptr++; + *bptr = regptr->paddr + regptr->cbcr_off; + bptr++; + } + } + + return rc; +} + +static int vfe_7x_config(struct msm_vfe_cfg_cmd *cmd, void *data) +{ + struct msm_pmem_region *regptr; + unsigned char buf[256]; + + struct vfe_stats_ack sack; + struct axidata *axid; + uint32_t i; + + struct vfe_stats_we_cfg *scfg = NULL; + struct vfe_stats_af_cfg *sfcfg = NULL; + + struct axiout *axio = NULL; + void *cmd_data = NULL; + void *cmd_data_alloc = NULL; + long rc = 0; + struct msm_vfe_command_7k *vfecmd; + + vfecmd = + kmalloc(sizeof(struct msm_vfe_command_7k), + GFP_ATOMIC); + if (!vfecmd) { + pr_err("vfecmd alloc failed!\n"); + return -ENOMEM; + } + + if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE && + cmd->cmd_type != CMD_STATS_BUF_RELEASE && + cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) { + if (copy_from_user(vfecmd, + (void __user *)(cmd->value), + sizeof(struct msm_vfe_command_7k))) { + rc = -EFAULT; + goto config_failure; + } + } + + switch (cmd->cmd_type) { + case CMD_STATS_ENABLE: + case CMD_STATS_AXI_CFG: { + axid = data; + if (!axid) { + rc = -EFAULT; + goto config_failure; + } + + scfg = + kmalloc(sizeof(struct vfe_stats_we_cfg), + GFP_ATOMIC); + if (!scfg) { + rc = -ENOMEM; + goto config_failure; + } + + if (copy_from_user(scfg, + (void __user *)(vfecmd->value), + vfecmd->length)) { + + rc = -EFAULT; + goto config_done; + } + + CDBG("STATS_ENABLE: bufnum = %d, enabling = %d\n", + axid->bufnum1, scfg->wb_expstatsenable); + + if (axid->bufnum1 > 0) { + regptr = axid->region; + + for (i = 0; i < axid->bufnum1; i++) { + + CDBG("STATS_ENABLE, phy = 0x%lx\n", + regptr->paddr); + + scfg->wb_expstatoutputbuffer[i] = + (void *)regptr->paddr; + regptr++; + } + + cmd_data = scfg; + + } else { + rc = -EINVAL; + goto config_done; + } + } + break; + + case CMD_STATS_AF_ENABLE: + case CMD_STATS_AF_AXI_CFG: { + axid = data; + if (!axid) { + rc = -EFAULT; + goto config_failure; + } + + sfcfg = + kmalloc(sizeof(struct vfe_stats_af_cfg), + GFP_ATOMIC); + + if (!sfcfg) { + rc = -ENOMEM; + goto config_failure; + } + + if (copy_from_user(sfcfg, + (void __user *)(vfecmd->value), + vfecmd->length)) { + + rc = -EFAULT; + goto config_done; + } + + CDBG("AF_ENABLE: bufnum = %d, enabling = %d\n", + axid->bufnum1, sfcfg->af_enable); + + if (axid->bufnum1 > 0) { + regptr = axid->region; + + for (i = 0; i < axid->bufnum1; i++) { + + CDBG("STATS_ENABLE, phy = 0x%lx\n", + regptr->paddr); + + sfcfg->af_outbuf[i] = + (void *)regptr->paddr; + + regptr++; + } + + cmd_data = sfcfg; + + } else { + rc = -EINVAL; + goto config_done; + } + } + break; + + case CMD_FRAME_BUF_RELEASE: { + struct msm_frame *b; + unsigned long p; + struct vfe_outputack fack; + if (!data) { + rc = -EFAULT; + goto config_failure; + } + + b = (struct msm_frame *)(cmd->value); + p = *(unsigned long *)data; + + fack.header = VFE_FRAME_ACK; + + fack.output2newybufferaddress = + (void *)(p + b->y_off); + + fack.output2newcbcrbufferaddress = + (void *)(p + b->cbcr_off); + + vfecmd->queue = QDSP_CMDQUEUE; + vfecmd->length = sizeof(struct vfe_outputack); + cmd_data = &fack; + } + break; + + case CMD_SNAP_BUF_RELEASE: + break; + + case CMD_STATS_BUF_RELEASE: { + CDBG("vfe_7x_config: CMD_STATS_BUF_RELEASE\n"); + if (!data) { + rc = -EFAULT; + goto config_failure; + } + + sack.header = STATS_WE_ACK; + sack.bufaddr = (void *)*(uint32_t *)data; + + vfecmd->queue = QDSP_CMDQUEUE; + vfecmd->length = sizeof(struct vfe_stats_ack); + cmd_data = &sack; + } + break; + + case CMD_STATS_AF_BUF_RELEASE: { + CDBG("vfe_7x_config: CMD_STATS_AF_BUF_RELEASE\n"); + if (!data) { + rc = -EFAULT; + goto config_failure; + } + + sack.header = STATS_AF_ACK; + sack.bufaddr = (void *)*(uint32_t *)data; + + vfecmd->queue = QDSP_CMDQUEUE; + vfecmd->length = sizeof(struct vfe_stats_ack); + cmd_data = &sack; + } + break; + + case CMD_GENERAL: + case CMD_STATS_DISABLE: { + if (vfecmd->length > 256) { + cmd_data_alloc = + cmd_data = kmalloc(vfecmd->length, GFP_ATOMIC); + if (!cmd_data) { + rc = -ENOMEM; + goto config_failure; + } + } else + cmd_data = buf; + + if (copy_from_user(cmd_data, + (void __user *)(vfecmd->value), + vfecmd->length)) { + + rc = -EFAULT; + goto config_done; + } + + if (vfecmd->queue == QDSP_CMDQUEUE) { + switch (*(uint32_t *)cmd_data) { + case VFE_RESET_CMD: + msm_camio_vfe_blk_reset(); + msm_camio_camif_pad_reg_reset_2(); + vfestopped = 0; + break; + + case VFE_START_CMD: + msm_camio_camif_pad_reg_reset_2(); + vfestopped = 0; + break; + + case VFE_STOP_CMD: + vfestopped = 1; + goto config_send; + + default: + break; + } + } /* QDSP_CMDQUEUE */ + } + break; + + case CMD_AXI_CFG_OUT1: { + axid = data; + if (!axid) { + rc = -EFAULT; + goto config_failure; + } + + axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC); + if (!axio) { + rc = -ENOMEM; + goto config_failure; + } + + if (copy_from_user(axio, (void *)(vfecmd->value), + sizeof(struct axiout))) { + rc = -EFAULT; + goto config_done; + } + + vfe_7x_config_axi(OUTPUT_1, axid, axio); + + cmd_data = axio; + } + break; + + case CMD_AXI_CFG_OUT2: + case CMD_RAW_PICT_AXI_CFG: { + axid = data; + if (!axid) { + rc = -EFAULT; + goto config_failure; + } + + axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC); + if (!axio) { + rc = -ENOMEM; + goto config_failure; + } + + if (copy_from_user(axio, (void __user *)(vfecmd->value), + sizeof(struct axiout))) { + rc = -EFAULT; + goto config_done; + } + + vfe_7x_config_axi(OUTPUT_2, axid, axio); + cmd_data = axio; + } + break; + + case CMD_AXI_CFG_SNAP_O1_AND_O2: { + axid = data; + if (!axid) { + rc = -EFAULT; + goto config_failure; + } + + axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC); + if (!axio) { + rc = -ENOMEM; + goto config_failure; + } + + if (copy_from_user(axio, (void __user *)(vfecmd->value), + sizeof(struct axiout))) { + rc = -EFAULT; + goto config_done; + } + + vfe_7x_config_axi(OUTPUT_1_AND_2, axid, axio); + + cmd_data = axio; + } + break; + + default: + break; + } /* switch */ + + if (vfestopped) + goto config_done; + +config_send: + CDBG("send adsp command = %d\n", *(uint32_t *)cmd_data); + rc = msm_adsp_write(vfe_mod, vfecmd->queue, + cmd_data, vfecmd->length); + +config_done: + if (cmd_data_alloc != NULL) + kfree(cmd_data_alloc); + +config_failure: + kfree(scfg); + kfree(axio); + kfree(vfecmd); + return rc; +} + +void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data) +{ + mutex_init(&vfe_lock); + fptr->vfe_init = vfe_7x_init; + fptr->vfe_enable = vfe_7x_enable; + fptr->vfe_config = vfe_7x_config; + fptr->vfe_disable = vfe_7x_disable; + fptr->vfe_release = vfe_7x_release; + vfe_syncdata = data; +} diff --git a/trunk/drivers/staging/dream/camera/msm_vfe7x.h b/trunk/drivers/staging/dream/camera/msm_vfe7x.h new file mode 100644 index 000000000000..be3e9ad8f524 --- /dev/null +++ b/trunk/drivers/staging/dream/camera/msm_vfe7x.h @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ +#ifndef __MSM_VFE7X_H__ +#define __MSM_VFE7X_H__ +#include +#include + +struct vfe_frame_extra { + uint32_t bl_evencol; + uint32_t bl_oddcol; + uint16_t g_def_p_cnt; + uint16_t r_b_def_p_cnt; +}; + +struct vfe_endframe { + uint32_t y_address; + uint32_t cbcr_address; + + unsigned int blacklevelevencolumn:23; + uint16_t reserved1:9; + unsigned int blackleveloddcolumn:23; + uint16_t reserved2:9; + + uint16_t greendefectpixelcount:8; + uint16_t reserved3:8; + uint16_t redbluedefectpixelcount:8; + uint16_t reserved4:8; +} __attribute__((packed, aligned(4))); + +struct vfe_outputack { + uint32_t header; + void *output2newybufferaddress; + void *output2newcbcrbufferaddress; +} __attribute__((packed, aligned(4))); + +struct vfe_stats_ack { + uint32_t header; + /* MUST BE 64 bit ALIGNED */ + void *bufaddr; +} __attribute__((packed, aligned(4))); + +/* AXI Output Config Command sent to DSP */ +struct axiout { + uint32_t cmdheader:32; + int outputmode:3; + uint8_t format:2; + uint32_t /* reserved */ : 27; + + /* AXI Output 1 Y Configuration, Part 1 */ + uint32_t out1yimageheight:12; + uint32_t /* reserved */ : 4; + uint32_t out1yimagewidthin64bitwords:10; + uint32_t /* reserved */ : 6; + + /* AXI Output 1 Y Configuration, Part 2 */ + uint8_t out1yburstlen:2; + uint32_t out1ynumrows:12; + uint32_t out1yrowincin64bitincs:12; + uint32_t /* reserved */ : 6; + + /* AXI Output 1 CbCr Configuration, Part 1 */ + uint32_t out1cbcrimageheight:12; + uint32_t /* reserved */ : 4; + uint32_t out1cbcrimagewidthin64bitwords:10; + uint32_t /* reserved */ : 6; + + /* AXI Output 1 CbCr Configuration, Part 2 */ + uint8_t out1cbcrburstlen:2; + uint32_t out1cbcrnumrows:12; + uint32_t out1cbcrrowincin64bitincs:12; + uint32_t /* reserved */ : 6; + + /* AXI Output 2 Y Configuration, Part 1 */ + uint32_t out2yimageheight:12; + uint32_t /* reserved */ : 4; + uint32_t out2yimagewidthin64bitwords:10; + uint32_t /* reserved */ : 6; + + /* AXI Output 2 Y Configuration, Part 2 */ + uint8_t out2yburstlen:2; + uint32_t out2ynumrows:12; + uint32_t out2yrowincin64bitincs:12; + uint32_t /* reserved */ : 6; + + /* AXI Output 2 CbCr Configuration, Part 1 */ + uint32_t out2cbcrimageheight:12; + uint32_t /* reserved */ : 4; + uint32_t out2cbcrimagewidtein64bitwords:10; + uint32_t /* reserved */ : 6; + + /* AXI Output 2 CbCr Configuration, Part 2 */ + uint8_t out2cbcrburstlen:2; + uint32_t out2cbcrnumrows:12; + uint32_t out2cbcrrowincin64bitincs:12; + uint32_t /* reserved */ : 6; + + /* Address configuration: + * output1 phisycal address */ + unsigned long output1buffer1_y_phy; + unsigned long output1buffer1_cbcr_phy; + unsigned long output1buffer2_y_phy; + unsigned long output1buffer2_cbcr_phy; + unsigned long output1buffer3_y_phy; + unsigned long output1buffer3_cbcr_phy; + unsigned long output1buffer4_y_phy; + unsigned long output1buffer4_cbcr_phy; + unsigned long output1buffer5_y_phy; + unsigned long output1buffer5_cbcr_phy; + unsigned long output1buffer6_y_phy; + unsigned long output1buffer6_cbcr_phy; + unsigned long output1buffer7_y_phy; + unsigned long output1buffer7_cbcr_phy; + unsigned long output1buffer8_y_phy; + unsigned long output1buffer8_cbcr_phy; + + /* output2 phisycal address */ + unsigned long output2buffer1_y_phy; + unsigned long output2buffer1_cbcr_phy; + unsigned long output2buffer2_y_phy; + unsigned long output2buffer2_cbcr_phy; + unsigned long output2buffer3_y_phy; + unsigned long output2buffer3_cbcr_phy; + unsigned long output2buffer4_y_phy; + unsigned long output2buffer4_cbcr_phy; + unsigned long output2buffer5_y_phy; + unsigned long output2buffer5_cbcr_phy; + unsigned long output2buffer6_y_phy; + unsigned long output2buffer6_cbcr_phy; + unsigned long output2buffer7_y_phy; + unsigned long output2buffer7_cbcr_phy; + unsigned long output2buffer8_y_phy; + unsigned long output2buffer8_cbcr_phy; +} __attribute__((packed, aligned(4))); + +struct vfe_stats_we_cfg { + uint32_t header; + + /* White Balance/Exposure Statistic Selection */ + uint8_t wb_expstatsenable:1; + uint8_t wb_expstatbuspriorityselection:1; + unsigned int wb_expstatbuspriorityvalue:4; + unsigned int /* reserved */ : 26; + + /* White Balance/Exposure Statistic Configuration, Part 1 */ + uint8_t exposurestatregions:1; + uint8_t exposurestatsubregions:1; + unsigned int /* reserved */ : 14; + + unsigned int whitebalanceminimumy:8; + unsigned int whitebalancemaximumy:8; + + /* White Balance/Exposure Statistic Configuration, Part 2 */ + uint8_t wb_expstatslopeofneutralregionline[ + NUM_WB_EXP_NEUTRAL_REGION_LINES]; + + /* White Balance/Exposure Statistic Configuration, Part 3 */ + unsigned int wb_expstatcrinterceptofneutralregionline2:12; + unsigned int /* reserved */ : 4; + unsigned int wb_expstatcbinterceptofneutralreginnline1:12; + unsigned int /* reserved */ : 4; + + /* White Balance/Exposure Statistic Configuration, Part 4 */ + unsigned int wb_expstatcrinterceptofneutralregionline4:12; + unsigned int /* reserved */ : 4; + unsigned int wb_expstatcbinterceptofneutralregionline3:12; + unsigned int /* reserved */ : 4; + + /* White Balance/Exposure Statistic Output Buffer Header */ + unsigned int wb_expmetricheaderpattern:8; + unsigned int /* reserved */ : 24; + + /* White Balance/Exposure Statistic Output Buffers-MUST + * BE 64 bit ALIGNED */ + void *wb_expstatoutputbuffer[NUM_WB_EXP_STAT_OUTPUT_BUFFERS]; +} __attribute__((packed, aligned(4))); + +struct vfe_stats_af_cfg { + uint32_t header; + + /* Autofocus Statistic Selection */ + uint8_t af_enable:1; + uint8_t af_busprioritysel:1; + unsigned int af_buspriorityval:4; + unsigned int /* reserved */ : 26; + + /* Autofocus Statistic Configuration, Part 1 */ + unsigned int af_singlewinvoffset:12; + unsigned int /* reserved */ : 4; + unsigned int af_singlewinhoffset:12; + unsigned int /* reserved */ : 3; + uint8_t af_winmode:1; + + /* Autofocus Statistic Configuration, Part 2 */ + unsigned int af_singglewinvh:11; + unsigned int /* reserved */ : 5; + unsigned int af_singlewinhw:11; + unsigned int /* reserved */ : 5; + + /* Autofocus Statistic Configuration, Parts 3-6 */ + uint8_t af_multiwingrid[NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS]; + + /* Autofocus Statistic Configuration, Part 7 */ + signed int af_metrichpfcoefa00:5; + signed int af_metrichpfcoefa04:5; + unsigned int af_metricmaxval:11; + uint8_t af_metricsel:1; + unsigned int /* reserved */ : 10; + + /* Autofocus Statistic Configuration, Part 8 */ + signed int af_metrichpfcoefa20:5; + signed int af_metrichpfcoefa21:5; + signed int af_metrichpfcoefa22:5; + signed int af_metrichpfcoefa23:5; + signed int af_metrichpfcoefa24:5; + unsigned int /* reserved */ : 7; + + /* Autofocus Statistic Output Buffer Header */ + unsigned int af_metrichp:8; + unsigned int /* reserved */ : 24; + + /* Autofocus Statistic Output Buffers - MUST BE 64 bit ALIGNED!!! */ + void *af_outbuf[NUM_AF_STAT_OUTPUT_BUFFERS]; +} __attribute__((packed, aligned(4))); /* VFE_StatsAutofocusConfigCmdType */ + +struct msm_camera_frame_msg { + unsigned long output_y_address; + unsigned long output_cbcr_address; + + unsigned int blacklevelevenColumn:23; + uint16_t reserved1:9; + unsigned int blackleveloddColumn:23; + uint16_t reserved2:9; + + uint16_t greendefectpixelcount:8; + uint16_t reserved3:8; + uint16_t redbluedefectpixelcount:8; + uint16_t reserved4:8; +} __attribute__((packed, aligned(4))); + +/* New one for 7k */ +struct msm_vfe_command_7k { + uint16_t queue; + uint16_t length; + void *value; +}; + +struct stop_event { + wait_queue_head_t wait; + int state; + int timeout; +}; + + +#endif /* __MSM_VFE7X_H__ */ diff --git a/trunk/drivers/staging/dream/camera/msm_vfe8x.c b/trunk/drivers/staging/dream/camera/msm_vfe8x.c new file mode 100644 index 000000000000..d87d56f914de --- /dev/null +++ b/trunk/drivers/staging/dream/camera/msm_vfe8x.c @@ -0,0 +1,736 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ +#include +#include +#include +#include +#include "msm_vfe8x_proc.h" + +#define ON 1 +#define OFF 0 + +struct mutex vfe_lock; +static void *vfe_syncdata; + +static int vfe_enable(struct camera_enable_cmd *enable) +{ + int rc = 0; + return rc; +} + +static int vfe_disable(struct camera_enable_cmd *enable, + struct platform_device *dev) +{ + int rc = 0; + + vfe_stop(); + + msm_camio_disable(dev); + return rc; +} + +static void vfe_release(struct platform_device *dev) +{ + msm_camio_disable(dev); + vfe_cmd_release(dev); + + mutex_lock(&vfe_lock); + vfe_syncdata = NULL; + mutex_unlock(&vfe_lock); +} + +static void vfe_config_axi(int mode, + struct axidata *ad, struct vfe_cmd_axi_output_config *ao) +{ + struct msm_pmem_region *regptr; + int i, j; + uint32_t *p1, *p2; + + if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) { + regptr = ad->region; + for (i = 0; + i < ad->bufnum1; i++) { + + p1 = &(ao->output1.outputY.outFragments[i][0]); + p2 = &(ao->output1.outputCbcr.outFragments[i][0]); + + for (j = 0; + j < ao->output1.fragmentCount; j++) { + + *p1 = regptr->paddr + regptr->y_off; + p1++; + + *p2 = regptr->paddr + regptr->cbcr_off; + p2++; + } + regptr++; + } + } /* if OUTPUT1 or Both */ + + if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) { + + regptr = &(ad->region[ad->bufnum1]); + CDBG("bufnum2 = %d\n", ad->bufnum2); + + for (i = 0; + i < ad->bufnum2; i++) { + + p1 = &(ao->output2.outputY.outFragments[i][0]); + p2 = &(ao->output2.outputCbcr.outFragments[i][0]); + + CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, cbcr_off = %d\n", + regptr->paddr, regptr->y_off, regptr->cbcr_off); + + for (j = 0; + j < ao->output2.fragmentCount; j++) { + + *p1 = regptr->paddr + regptr->y_off; + CDBG("vfe_config_axi: p1 = 0x%x\n", *p1); + p1++; + + *p2 = regptr->paddr + regptr->cbcr_off; + CDBG("vfe_config_axi: p2 = 0x%x\n", *p2); + p2++; + } + regptr++; + } + } +} + +static int vfe_proc_general(struct msm_vfe_command_8k *cmd) +{ + int rc = 0; + + CDBG("vfe_proc_general: cmdID = %d\n", cmd->id); + + switch (cmd->id) { + case VFE_CMD_ID_RESET: + msm_camio_vfe_blk_reset(); + msm_camio_camif_pad_reg_reset_2(); + vfe_reset(); + break; + + case VFE_CMD_ID_START: { + struct vfe_cmd_start start; + if (copy_from_user(&start, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + /* msm_camio_camif_pad_reg_reset_2(); */ + msm_camio_camif_pad_reg_reset(); + vfe_start(&start); + } + break; + + case VFE_CMD_ID_CAMIF_CONFIG: { + struct vfe_cmd_camif_config camif; + if (copy_from_user(&camif, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_camif_config(&camif); + } + break; + + case VFE_CMD_ID_BLACK_LEVEL_CONFIG: { + struct vfe_cmd_black_level_config bl; + if (copy_from_user(&bl, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_black_level_config(&bl); + } + break; + + case VFE_CMD_ID_ROLL_OFF_CONFIG: { + struct vfe_cmd_roll_off_config rolloff; + if (copy_from_user(&rolloff, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_roll_off_config(&rolloff); + } + break; + + case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG: { + struct vfe_cmd_demux_channel_gain_config demuxc; + if (copy_from_user(&demuxc, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + /* demux is always enabled. */ + vfe_demux_channel_gain_config(&demuxc); + } + break; + + case VFE_CMD_ID_DEMOSAIC_CONFIG: { + struct vfe_cmd_demosaic_config demosaic; + if (copy_from_user(&demosaic, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_demosaic_config(&demosaic); + } + break; + + case VFE_CMD_ID_FOV_CROP_CONFIG: + case VFE_CMD_ID_FOV_CROP_UPDATE: { + struct vfe_cmd_fov_crop_config fov; + if (copy_from_user(&fov, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_fov_crop_config(&fov); + } + break; + + case VFE_CMD_ID_MAIN_SCALER_CONFIG: + case VFE_CMD_ID_MAIN_SCALER_UPDATE: { + struct vfe_cmd_main_scaler_config mainds; + if (copy_from_user(&mainds, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_main_scaler_config(&mainds); + } + break; + + case VFE_CMD_ID_WHITE_BALANCE_CONFIG: + case VFE_CMD_ID_WHITE_BALANCE_UPDATE: { + struct vfe_cmd_white_balance_config wb; + if (copy_from_user(&wb, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_white_balance_config(&wb); + } + break; + + case VFE_CMD_ID_COLOR_CORRECTION_CONFIG: + case VFE_CMD_ID_COLOR_CORRECTION_UPDATE: { + struct vfe_cmd_color_correction_config cc; + if (copy_from_user(&cc, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_color_correction_config(&cc); + } + break; + + case VFE_CMD_ID_LA_CONFIG: { + struct vfe_cmd_la_config la; + if (copy_from_user(&la, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_la_config(&la); + } + break; + + case VFE_CMD_ID_RGB_GAMMA_CONFIG: { + struct vfe_cmd_rgb_gamma_config rgb; + if (copy_from_user(&rgb, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + rc = vfe_rgb_gamma_config(&rgb); + } + break; + + case VFE_CMD_ID_CHROMA_ENHAN_CONFIG: + case VFE_CMD_ID_CHROMA_ENHAN_UPDATE: { + struct vfe_cmd_chroma_enhan_config chrom; + if (copy_from_user(&chrom, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_chroma_enhan_config(&chrom); + } + break; + + case VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG: + case VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE: { + struct vfe_cmd_chroma_suppression_config chromsup; + if (copy_from_user(&chromsup, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_chroma_sup_config(&chromsup); + } + break; + + case VFE_CMD_ID_ASF_CONFIG: { + struct vfe_cmd_asf_config asf; + if (copy_from_user(&asf, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_asf_config(&asf); + } + break; + + case VFE_CMD_ID_SCALER2Y_CONFIG: + case VFE_CMD_ID_SCALER2Y_UPDATE: { + struct vfe_cmd_scaler2_config ds2y; + if (copy_from_user(&ds2y, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_scaler2y_config(&ds2y); + } + break; + + case VFE_CMD_ID_SCALER2CbCr_CONFIG: + case VFE_CMD_ID_SCALER2CbCr_UPDATE: { + struct vfe_cmd_scaler2_config ds2cbcr; + if (copy_from_user(&ds2cbcr, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_scaler2cbcr_config(&ds2cbcr); + } + break; + + case VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG: { + struct vfe_cmd_chroma_subsample_config sub; + if (copy_from_user(&sub, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_chroma_subsample_config(&sub); + } + break; + + case VFE_CMD_ID_FRAME_SKIP_CONFIG: { + struct vfe_cmd_frame_skip_config fskip; + if (copy_from_user(&fskip, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_frame_skip_config(&fskip); + } + break; + + case VFE_CMD_ID_OUTPUT_CLAMP_CONFIG: { + struct vfe_cmd_output_clamp_config clamp; + if (copy_from_user(&clamp, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_output_clamp_config(&clamp); + } + break; + + /* module update commands */ + case VFE_CMD_ID_BLACK_LEVEL_UPDATE: { + struct vfe_cmd_black_level_config blk; + if (copy_from_user(&blk, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_black_level_update(&blk); + } + break; + + case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE: { + struct vfe_cmd_demux_channel_gain_config dmu; + if (copy_from_user(&dmu, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_demux_channel_gain_update(&dmu); + } + break; + + case VFE_CMD_ID_DEMOSAIC_BPC_UPDATE: { + struct vfe_cmd_demosaic_bpc_update demo_bpc; + if (copy_from_user(&demo_bpc, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_demosaic_bpc_update(&demo_bpc); + } + break; + + case VFE_CMD_ID_DEMOSAIC_ABF_UPDATE: { + struct vfe_cmd_demosaic_abf_update demo_abf; + if (copy_from_user(&demo_abf, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_demosaic_abf_update(&demo_abf); + } + break; + + case VFE_CMD_ID_LA_UPDATE: { + struct vfe_cmd_la_config la; + if (copy_from_user(&la, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_la_update(&la); + } + break; + + case VFE_CMD_ID_RGB_GAMMA_UPDATE: { + struct vfe_cmd_rgb_gamma_config rgb; + if (copy_from_user(&rgb, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + rc = vfe_rgb_gamma_update(&rgb); + } + break; + + case VFE_CMD_ID_ASF_UPDATE: { + struct vfe_cmd_asf_update asf; + if (copy_from_user(&asf, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_asf_update(&asf); + } + break; + + case VFE_CMD_ID_FRAME_SKIP_UPDATE: { + struct vfe_cmd_frame_skip_update fskip; + if (copy_from_user(&fskip, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_frame_skip_update(&fskip); + } + break; + + case VFE_CMD_ID_CAMIF_FRAME_UPDATE: { + struct vfe_cmds_camif_frame fup; + if (copy_from_user(&fup, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_camif_frame_update(&fup); + } + break; + + /* stats update commands */ + case VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE: { + struct vfe_cmd_stats_af_update afup; + if (copy_from_user(&afup, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_stats_update_af(&afup); + } + break; + + case VFE_CMD_ID_STATS_WB_EXP_UPDATE: { + struct vfe_cmd_stats_wb_exp_update wbexp; + if (copy_from_user(&wbexp, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_stats_update_wb_exp(&wbexp); + } + break; + + /* control of start, stop, update, etc... */ + case VFE_CMD_ID_STOP: + vfe_stop(); + break; + + case VFE_CMD_ID_GET_HW_VERSION: + break; + + /* stats */ + case VFE_CMD_ID_STATS_SETTING: { + struct vfe_cmd_stats_setting stats; + if (copy_from_user(&stats, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_stats_setting(&stats); + } + break; + + case VFE_CMD_ID_STATS_AUTOFOCUS_START: { + struct vfe_cmd_stats_af_start af; + if (copy_from_user(&af, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_stats_start_af(&af); + } + break; + + case VFE_CMD_ID_STATS_AUTOFOCUS_STOP: + vfe_stats_af_stop(); + break; + + case VFE_CMD_ID_STATS_WB_EXP_START: { + struct vfe_cmd_stats_wb_exp_start awexp; + if (copy_from_user(&awexp, + (void __user *) cmd->value, cmd->length)) + rc = -EFAULT; + + vfe_stats_start_wb_exp(&awexp); + } + break; + + case VFE_CMD_ID_STATS_WB_EXP_STOP: + vfe_stats_wb_exp_stop(); + break; + + case VFE_CMD_ID_ASYNC_TIMER_SETTING: + break; + + case VFE_CMD_ID_UPDATE: + vfe_update(); + break; + + /* test gen */ + case VFE_CMD_ID_TEST_GEN_START: + break; + +/* + acknowledge from upper layer + these are not in general command. + + case VFE_CMD_ID_OUTPUT1_ACK: + break; + case VFE_CMD_ID_OUTPUT2_ACK: + break; + case VFE_CMD_ID_EPOCH1_ACK: + break; + case VFE_CMD_ID_EPOCH2_ACK: + break; + case VFE_CMD_ID_STATS_AUTOFOCUS_ACK: + break; + case VFE_CMD_ID_STATS_WB_EXP_ACK: + break; +*/ + + default: + break; + } /* switch */ + + return rc; +} + +static int vfe_config(struct msm_vfe_cfg_cmd *cmd, void *data) +{ + struct msm_pmem_region *regptr; + struct msm_vfe_command_8k vfecmd; + + uint32_t i; + + void *cmd_data = NULL; + long rc = 0; + + struct vfe_cmd_axi_output_config *axio = NULL; + struct vfe_cmd_stats_setting *scfg = NULL; + + if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE && + cmd->cmd_type != CMD_STATS_BUF_RELEASE) { + + if (copy_from_user(&vfecmd, + (void __user *)(cmd->value), + sizeof(struct msm_vfe_command_8k))) + return -EFAULT; + } + + CDBG("vfe_config: cmdType = %d\n", cmd->cmd_type); + + switch (cmd->cmd_type) { + case CMD_GENERAL: + rc = vfe_proc_general(&vfecmd); + break; + + case CMD_STATS_ENABLE: + case CMD_STATS_AXI_CFG: { + struct axidata *axid; + + axid = data; + if (!axid) + return -EFAULT; + + scfg = + kmalloc(sizeof(struct vfe_cmd_stats_setting), + GFP_ATOMIC); + if (!scfg) + return -ENOMEM; + + if (copy_from_user(scfg, + (void __user *)(vfecmd.value), + vfecmd.length)) { + + kfree(scfg); + return -EFAULT; + } + + regptr = axid->region; + if (axid->bufnum1 > 0) { + for (i = 0; i < axid->bufnum1; i++) { + scfg->awbBuffer[i] = + (uint32_t)(regptr->paddr); + regptr++; + } + } + + if (axid->bufnum2 > 0) { + for (i = 0; i < axid->bufnum2; i++) { + scfg->afBuffer[i] = + (uint32_t)(regptr->paddr); + regptr++; + } + } + + vfe_stats_config(scfg); + } + break; + + case CMD_STATS_AF_AXI_CFG: { + } + break; + + case CMD_FRAME_BUF_RELEASE: { + /* preview buffer release */ + struct msm_frame *b; + unsigned long p; + struct vfe_cmd_output_ack fack; + + if (!data) + return -EFAULT; + + b = (struct msm_frame *)(cmd->value); + p = *(unsigned long *)data; + + b->path = MSM_FRAME_ENC; + + fack.ybufaddr[0] = + (uint32_t)(p + b->y_off); + + fack.chromabufaddr[0] = + (uint32_t)(p + b->cbcr_off); + + if (b->path == MSM_FRAME_PREV_1) + vfe_output1_ack(&fack); + + if (b->path == MSM_FRAME_ENC || + b->path == MSM_FRAME_PREV_2) + vfe_output2_ack(&fack); + } + break; + + case CMD_SNAP_BUF_RELEASE: { + } + break; + + case CMD_STATS_BUF_RELEASE: { + struct vfe_cmd_stats_wb_exp_ack sack; + + if (!data) + return -EFAULT; + + sack.nextWbExpOutputBufferAddr = *(uint32_t *)data; + vfe_stats_wb_exp_ack(&sack); + } + break; + + case CMD_AXI_CFG_OUT1: { + struct axidata *axid; + + axid = data; + if (!axid) + return -EFAULT; + + axio = memdup_user((void __user *)(vfecmd.value), + sizeof(struct vfe_cmd_axi_output_config)); + if (IS_ERR(axio)) + return PTR_ERR(axio); + + vfe_config_axi(OUTPUT_1, axid, axio); + vfe_axi_output_config(axio); + } + break; + + case CMD_AXI_CFG_OUT2: + case CMD_RAW_PICT_AXI_CFG: { + struct axidata *axid; + + axid = data; + if (!axid) + return -EFAULT; + + axio = memdup_user((void __user *)(vfecmd.value), + sizeof(struct vfe_cmd_axi_output_config)); + if (IS_ERR(axio)) + return PTR_ERR(axio); + + vfe_config_axi(OUTPUT_2, axid, axio); + + axio->outputDataSize = 0; + vfe_axi_output_config(axio); + } + break; + + case CMD_AXI_CFG_SNAP_O1_AND_O2: { + struct axidata *axid; + axid = data; + if (!axid) + return -EFAULT; + + axio = memdup_user((void __user *)(vfecmd.value), + sizeof(struct vfe_cmd_axi_output_config)); + if (IS_ERR(axio)) + return PTR_ERR(axio); + + vfe_config_axi(OUTPUT_1_AND_2, + axid, axio); + vfe_axi_output_config(axio); + cmd_data = axio; + } + break; + + default: + break; + } /* switch */ + + kfree(scfg); + + kfree(axio); + +/* + if (cmd->length > 256 && + cmd_data && + (cmd->cmd_type == CMD_GENERAL || + cmd->cmd_type == CMD_STATS_DISABLE)) { + kfree(cmd_data); + } +*/ + return rc; +} + +static int vfe_init(struct msm_vfe_callback *presp, + struct platform_device *dev) +{ + int rc = 0; + + rc = vfe_cmd_init(presp, dev, vfe_syncdata); + if (rc < 0) + return rc; + + /* Bring up all the required GPIOs and Clocks */ + return msm_camio_enable(dev); +} + +void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data) +{ + mutex_init(&vfe_lock); + fptr->vfe_init = vfe_init; + fptr->vfe_enable = vfe_enable; + fptr->vfe_config = vfe_config; + fptr->vfe_disable = vfe_disable; + fptr->vfe_release = vfe_release; + vfe_syncdata = data; +} diff --git a/trunk/drivers/staging/dream/camera/msm_vfe8x.h b/trunk/drivers/staging/dream/camera/msm_vfe8x.h new file mode 100644 index 000000000000..28a70a9e5ed7 --- /dev/null +++ b/trunk/drivers/staging/dream/camera/msm_vfe8x.h @@ -0,0 +1,895 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ +#ifndef __MSM_VFE8X_H__ +#define __MSM_VFE8X_H__ + +#define TRUE 1 +#define FALSE 0 +#define boolean uint8_t + +enum VFE_STATE { + VFE_STATE_IDLE, + VFE_STATE_ACTIVE +}; + +enum vfe_cmd_id { + /* + *Important! Command_ID are arranged in order. + *Don't change!*/ + VFE_CMD_ID_START, + VFE_CMD_ID_RESET, + + /* bus and camif config */ + VFE_CMD_ID_AXI_INPUT_CONFIG, + VFE_CMD_ID_CAMIF_CONFIG, + VFE_CMD_ID_AXI_OUTPUT_CONFIG, + + /* module config */ + VFE_CMD_ID_BLACK_LEVEL_CONFIG, + VFE_CMD_ID_ROLL_OFF_CONFIG, + VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG, + VFE_CMD_ID_DEMOSAIC_CONFIG, + VFE_CMD_ID_FOV_CROP_CONFIG, + VFE_CMD_ID_MAIN_SCALER_CONFIG, + VFE_CMD_ID_WHITE_BALANCE_CONFIG, + VFE_CMD_ID_COLOR_CORRECTION_CONFIG, + VFE_CMD_ID_LA_CONFIG, + VFE_CMD_ID_RGB_GAMMA_CONFIG, + VFE_CMD_ID_CHROMA_ENHAN_CONFIG, + VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG, + VFE_CMD_ID_ASF_CONFIG, + VFE_CMD_ID_SCALER2Y_CONFIG, + VFE_CMD_ID_SCALER2CbCr_CONFIG, + VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG, + VFE_CMD_ID_FRAME_SKIP_CONFIG, + VFE_CMD_ID_OUTPUT_CLAMP_CONFIG, + + /* test gen */ + VFE_CMD_ID_TEST_GEN_START, + + VFE_CMD_ID_UPDATE, + + /* ackownledge from upper layer */ + VFE_CMD_ID_OUTPUT1_ACK, + VFE_CMD_ID_OUTPUT2_ACK, + VFE_CMD_ID_EPOCH1_ACK, + VFE_CMD_ID_EPOCH2_ACK, + VFE_CMD_ID_STATS_AUTOFOCUS_ACK, + VFE_CMD_ID_STATS_WB_EXP_ACK, + + /* module update commands */ + VFE_CMD_ID_BLACK_LEVEL_UPDATE, + VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE, + VFE_CMD_ID_DEMOSAIC_BPC_UPDATE, + VFE_CMD_ID_DEMOSAIC_ABF_UPDATE, + VFE_CMD_ID_FOV_CROP_UPDATE, + VFE_CMD_ID_WHITE_BALANCE_UPDATE, + VFE_CMD_ID_COLOR_CORRECTION_UPDATE, + VFE_CMD_ID_LA_UPDATE, + VFE_CMD_ID_RGB_GAMMA_UPDATE, + VFE_CMD_ID_CHROMA_ENHAN_UPDATE, + VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE, + VFE_CMD_ID_MAIN_SCALER_UPDATE, + VFE_CMD_ID_SCALER2CbCr_UPDATE, + VFE_CMD_ID_SCALER2Y_UPDATE, + VFE_CMD_ID_ASF_UPDATE, + VFE_CMD_ID_FRAME_SKIP_UPDATE, + VFE_CMD_ID_CAMIF_FRAME_UPDATE, + + /* stats update commands */ + VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE, + VFE_CMD_ID_STATS_WB_EXP_UPDATE, + + /* control of start, stop, update, etc... */ + VFE_CMD_ID_STOP, + VFE_CMD_ID_GET_HW_VERSION, + + /* stats */ + VFE_CMD_ID_STATS_SETTING, + VFE_CMD_ID_STATS_AUTOFOCUS_START, + VFE_CMD_ID_STATS_AUTOFOCUS_STOP, + VFE_CMD_ID_STATS_WB_EXP_START, + VFE_CMD_ID_STATS_WB_EXP_STOP, + + VFE_CMD_ID_ASYNC_TIMER_SETTING, + + /* max id */ + VFE_CMD_ID_MAX +}; + +struct vfe_cmd_hw_version { + uint32_t minorVersion; + uint32_t majorVersion; + uint32_t coreVersion; +}; + +enum VFE_CAMIF_SYNC_EDGE { + VFE_CAMIF_SYNC_EDGE_ActiveHigh, + VFE_CAMIF_SYNC_EDGE_ActiveLow +}; + +enum VFE_CAMIF_SYNC_MODE { + VFE_CAMIF_SYNC_MODE_APS, + VFE_CAMIF_SYNC_MODE_EFS, + VFE_CAMIF_SYNC_MODE_ELS, + VFE_CAMIF_SYNC_MODE_ILLEGAL +}; + +struct vfe_cmds_camif_efs { + uint8_t efsendofline; + uint8_t efsstartofline; + uint8_t efsendofframe; + uint8_t efsstartofframe; +}; + +struct vfe_cmds_camif_frame { + uint16_t pixelsPerLine; + uint16_t linesPerFrame; +}; + +struct vfe_cmds_camif_window { + uint16_t firstpixel; + uint16_t lastpixel; + uint16_t firstline; + uint16_t lastline; +}; + +enum CAMIF_SUBSAMPLE_FRAME_SKIP { + CAMIF_SUBSAMPLE_FRAME_SKIP_0, + CAMIF_SUBSAMPLE_FRAME_SKIP_AllFrames, + CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_2Frame, + CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_3Frame, + CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_4Frame, + CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_5Frame, + CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_6Frame, + CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_7Frame, + CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_8Frame, + CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_9Frame, + CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_10Frame, + CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_11Frame, + CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_12Frame, + CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_13Frame, + CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_14Frame, + CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_15Frame +}; + +struct vfe_cmds_camif_subsample { + uint16_t pixelskipmask; + uint16_t lineskipmask; + enum CAMIF_SUBSAMPLE_FRAME_SKIP frameskip; + uint8_t frameskipmode; + uint8_t pixelskipwrap; +}; + +struct vfe_cmds_camif_epoch { + uint8_t enable; + uint16_t lineindex; +}; + +struct vfe_cmds_camif_cfg { + enum VFE_CAMIF_SYNC_EDGE vSyncEdge; + enum VFE_CAMIF_SYNC_EDGE hSyncEdge; + enum VFE_CAMIF_SYNC_MODE syncMode; + uint8_t vfeSubSampleEnable; + uint8_t busSubSampleEnable; + uint8_t irqSubSampleEnable; + uint8_t binningEnable; + uint8_t misrEnable; +}; + +struct vfe_cmd_camif_config { + struct vfe_cmds_camif_cfg camifConfig; + struct vfe_cmds_camif_efs EFS; + struct vfe_cmds_camif_frame frame; + struct vfe_cmds_camif_window window; + struct vfe_cmds_camif_subsample subsample; + struct vfe_cmds_camif_epoch epoch1; + struct vfe_cmds_camif_epoch epoch2; +}; + +enum VFE_AXI_OUTPUT_MODE { + VFE_AXI_OUTPUT_MODE_Output1, + VFE_AXI_OUTPUT_MODE_Output2, + VFE_AXI_OUTPUT_MODE_Output1AndOutput2, + VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2, + VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1, + VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2, + VFE_AXI_LAST_OUTPUT_MODE_ENUM +}; + +enum VFE_RAW_WR_PATH_SEL { + VFE_RAW_OUTPUT_DISABLED, + VFE_RAW_OUTPUT_ENC_CBCR_PATH, + VFE_RAW_OUTPUT_VIEW_CBCR_PATH, + VFE_RAW_OUTPUT_PATH_INVALID +}; + +enum VFE_RAW_PIXEL_DATA_SIZE { + VFE_RAW_PIXEL_DATA_SIZE_8BIT, + VFE_RAW_PIXEL_DATA_SIZE_10BIT, + VFE_RAW_PIXEL_DATA_SIZE_12BIT, +}; + +#define VFE_AXI_OUTPUT_BURST_LENGTH 4 +#define VFE_MAX_NUM_FRAGMENTS_PER_FRAME 4 +#define VFE_AXI_OUTPUT_CFG_FRAME_COUNT 3 + +struct vfe_cmds_axi_out_per_component { + uint16_t imageWidth; + uint16_t imageHeight; + uint16_t outRowCount; + uint16_t outRowIncrement; + uint32_t outFragments[VFE_AXI_OUTPUT_CFG_FRAME_COUNT] + [VFE_MAX_NUM_FRAGMENTS_PER_FRAME]; +}; + +struct vfe_cmds_axi_per_output_path { + uint8_t fragmentCount; + struct vfe_cmds_axi_out_per_component outputY; + struct vfe_cmds_axi_out_per_component outputCbcr; +}; + +enum VFE_AXI_BURST_LENGTH { + VFE_AXI_BURST_LENGTH_IS_2 = 2, + VFE_AXI_BURST_LENGTH_IS_4 = 4, + VFE_AXI_BURST_LENGTH_IS_8 = 8, + VFE_AXI_BURST_LENGTH_IS_16 = 16 +}; + +struct vfe_cmd_axi_output_config { + enum VFE_AXI_BURST_LENGTH burstLength; + enum VFE_AXI_OUTPUT_MODE outputMode; + enum VFE_RAW_PIXEL_DATA_SIZE outputDataSize; + struct vfe_cmds_axi_per_output_path output1; + struct vfe_cmds_axi_per_output_path output2; +}; + +struct vfe_cmd_fov_crop_config { + uint8_t enable; + uint16_t firstPixel; + uint16_t lastPixel; + uint16_t firstLine; + uint16_t lastLine; +}; + +struct vfe_cmds_main_scaler_stripe_init { + uint16_t MNCounterInit; + uint16_t phaseInit; +}; + +struct vfe_cmds_scaler_one_dimension { + uint8_t enable; + uint16_t inputSize; + uint16_t outputSize; + uint32_t phaseMultiplicationFactor; + uint8_t interpolationResolution; +}; + +struct vfe_cmd_main_scaler_config { + uint8_t enable; + struct vfe_cmds_scaler_one_dimension hconfig; + struct vfe_cmds_scaler_one_dimension vconfig; + struct vfe_cmds_main_scaler_stripe_init MNInitH; + struct vfe_cmds_main_scaler_stripe_init MNInitV; +}; + +struct vfe_cmd_scaler2_config { + uint8_t enable; + struct vfe_cmds_scaler_one_dimension hconfig; + struct vfe_cmds_scaler_one_dimension vconfig; +}; + +struct vfe_cmd_frame_skip_config { + uint8_t output1Period; + uint32_t output1Pattern; + uint8_t output2Period; + uint32_t output2Pattern; +}; + +struct vfe_cmd_frame_skip_update { + uint32_t output1Pattern; + uint32_t output2Pattern; +}; + +struct vfe_cmd_output_clamp_config { + uint8_t minCh0; + uint8_t minCh1; + uint8_t minCh2; + uint8_t maxCh0; + uint8_t maxCh1; + uint8_t maxCh2; +}; + +struct vfe_cmd_chroma_subsample_config { + uint8_t enable; + uint8_t cropEnable; + uint8_t vsubSampleEnable; + uint8_t hsubSampleEnable; + uint8_t vCosited; + uint8_t hCosited; + uint8_t vCositedPhase; + uint8_t hCositedPhase; + uint16_t cropWidthFirstPixel; + uint16_t cropWidthLastPixel; + uint16_t cropHeightFirstLine; + uint16_t cropHeightLastLine; +}; + +enum VFE_START_INPUT_SOURCE { + VFE_START_INPUT_SOURCE_CAMIF, + VFE_START_INPUT_SOURCE_TESTGEN, + VFE_START_INPUT_SOURCE_AXI, + VFE_START_INPUT_SOURCE_INVALID +}; + +enum VFE_START_OPERATION_MODE { + VFE_START_OPERATION_MODE_CONTINUOUS, + VFE_START_OPERATION_MODE_SNAPSHOT +}; + +enum VFE_START_PIXEL_PATTERN { + VFE_BAYER_RGRGRG, + VFE_BAYER_GRGRGR, + VFE_BAYER_BGBGBG, + VFE_BAYER_GBGBGB, + VFE_YUV_YCbYCr, + VFE_YUV_YCrYCb, + VFE_YUV_CbYCrY, + VFE_YUV_CrYCbY +}; + +enum VFE_BUS_RD_INPUT_PIXEL_PATTERN { + VFE_BAYER_RAW, + VFE_YUV_INTERLEAVED, + VFE_YUV_PSEUDO_PLANAR_Y, + VFE_YUV_PSEUDO_PLANAR_CBCR +}; + +enum VFE_YUV_INPUT_COSITING_MODE { + VFE_YUV_COSITED, + VFE_YUV_INTERPOLATED +}; + +struct vfe_cmd_start { + enum VFE_START_INPUT_SOURCE inputSource; + enum VFE_START_OPERATION_MODE operationMode; + uint8_t snapshotCount; + enum VFE_START_PIXEL_PATTERN pixel; + enum VFE_YUV_INPUT_COSITING_MODE yuvInputCositingMode; +}; + +struct vfe_cmd_output_ack { + uint32_t ybufaddr[VFE_MAX_NUM_FRAGMENTS_PER_FRAME]; + uint32_t chromabufaddr[VFE_MAX_NUM_FRAGMENTS_PER_FRAME]; +}; + +#define VFE_STATS_BUFFER_COUNT 3 + +struct vfe_cmd_stats_setting { + uint16_t frameHDimension; + uint16_t frameVDimension; + uint8_t afBusPrioritySelection; + uint8_t afBusPriority; + uint8_t awbBusPrioritySelection; + uint8_t awbBusPriority; + uint8_t histBusPrioritySelection; + uint8_t histBusPriority; + uint32_t afBuffer[VFE_STATS_BUFFER_COUNT]; + uint32_t awbBuffer[VFE_STATS_BUFFER_COUNT]; + uint32_t histBuffer[VFE_STATS_BUFFER_COUNT]; +}; + +struct vfe_cmd_stats_af_start { + uint8_t enable; + uint8_t windowMode; + uint16_t windowHOffset; + uint16_t windowVOffset; + uint16_t windowWidth; + uint16_t windowHeight; + uint8_t gridForMultiWindows[16]; + uint8_t metricSelection; + int16_t metricMax; + int8_t highPassCoef[7]; + int8_t bufferHeader; +}; + +struct vfe_cmd_stats_af_update { + uint8_t windowMode; + uint16_t windowHOffset; + uint16_t windowVOffset; + uint16_t windowWidth; + uint16_t windowHeight; +}; + +struct vfe_cmd_stats_wb_exp_start { + uint8_t enable; + uint8_t wbExpRegions; + uint8_t wbExpSubRegion; + uint8_t awbYMin; + uint8_t awbYMax; + int8_t awbMCFG[4]; + int16_t awbCCFG[4]; + int8_t axwHeader; +}; + +struct vfe_cmd_stats_wb_exp_update { + uint8_t wbExpRegions; + uint8_t wbExpSubRegion; + int8_t awbYMin; + int8_t awbYMax; + int8_t awbMCFG[4]; + int16_t awbCCFG[4]; +}; + +struct vfe_cmd_stats_af_ack { + uint32_t nextAFOutputBufferAddr; +}; + +struct vfe_cmd_stats_wb_exp_ack { + uint32_t nextWbExpOutputBufferAddr; +}; + +struct vfe_cmd_black_level_config { + uint8_t enable; + uint16_t evenEvenAdjustment; + uint16_t evenOddAdjustment; + uint16_t oddEvenAdjustment; + uint16_t oddOddAdjustment; +}; + +/* 13*1 */ +#define VFE_ROLL_OFF_INIT_TABLE_SIZE 13 +/* 13*16 */ +#define VFE_ROLL_OFF_DELTA_TABLE_SIZE 208 + +struct vfe_cmd_roll_off_config { + uint8_t enable; + uint16_t gridWidth; + uint16_t gridHeight; + uint16_t yDelta; + uint8_t gridXIndex; + uint8_t gridYIndex; + uint16_t gridPixelXIndex; + uint16_t gridPixelYIndex; + uint16_t yDeltaAccum; + uint16_t initTableR[VFE_ROLL_OFF_INIT_TABLE_SIZE]; + uint16_t initTableGr[VFE_ROLL_OFF_INIT_TABLE_SIZE]; + uint16_t initTableB[VFE_ROLL_OFF_INIT_TABLE_SIZE]; + uint16_t initTableGb[VFE_ROLL_OFF_INIT_TABLE_SIZE]; + int16_t deltaTableR[VFE_ROLL_OFF_DELTA_TABLE_SIZE]; + int16_t deltaTableGr[VFE_ROLL_OFF_DELTA_TABLE_SIZE]; + int16_t deltaTableB[VFE_ROLL_OFF_DELTA_TABLE_SIZE]; + int16_t deltaTableGb[VFE_ROLL_OFF_DELTA_TABLE_SIZE]; +}; + +struct vfe_cmd_demux_channel_gain_config { + uint16_t ch0EvenGain; + uint16_t ch0OddGain; + uint16_t ch1Gain; + uint16_t ch2Gain; +}; + +struct vfe_cmds_demosaic_abf { + uint8_t enable; + uint8_t forceOn; + uint8_t shift; + uint16_t lpThreshold; + uint16_t max; + uint16_t min; + uint8_t ratio; +}; + +struct vfe_cmds_demosaic_bpc { + uint8_t enable; + uint16_t fmaxThreshold; + uint16_t fminThreshold; + uint16_t redDiffThreshold; + uint16_t blueDiffThreshold; + uint16_t greenDiffThreshold; +}; + +struct vfe_cmd_demosaic_config { + uint8_t enable; + uint8_t slopeShift; + struct vfe_cmds_demosaic_abf abfConfig; + struct vfe_cmds_demosaic_bpc bpcConfig; +}; + +struct vfe_cmd_demosaic_bpc_update { + struct vfe_cmds_demosaic_bpc bpcUpdate; +}; + +struct vfe_cmd_demosaic_abf_update { + struct vfe_cmds_demosaic_abf abfUpdate; +}; + +struct vfe_cmd_white_balance_config { + uint8_t enable; + uint16_t ch2Gain; + uint16_t ch1Gain; + uint16_t ch0Gain; +}; + +enum VFE_COLOR_CORRECTION_COEF_QFACTOR { + COEF_IS_Q7_SIGNED, + COEF_IS_Q8_SIGNED, + COEF_IS_Q9_SIGNED, + COEF_IS_Q10_SIGNED +}; + +struct vfe_cmd_color_correction_config { + uint8_t enable; + enum VFE_COLOR_CORRECTION_COEF_QFACTOR coefQFactor; + int16_t C0; + int16_t C1; + int16_t C2; + int16_t C3; + int16_t C4; + int16_t C5; + int16_t C6; + int16_t C7; + int16_t C8; + int16_t K0; + int16_t K1; + int16_t K2; +}; + +#define VFE_LA_TABLE_LENGTH 256 +struct vfe_cmd_la_config { + uint8_t enable; + int16_t table[VFE_LA_TABLE_LENGTH]; +}; + +#define VFE_GAMMA_TABLE_LENGTH 256 +enum VFE_RGB_GAMMA_TABLE_SELECT { + RGB_GAMMA_CH0_SELECTED, + RGB_GAMMA_CH1_SELECTED, + RGB_GAMMA_CH2_SELECTED, + RGB_GAMMA_CH0_CH1_SELECTED, + RGB_GAMMA_CH0_CH2_SELECTED, + RGB_GAMMA_CH1_CH2_SELECTED, + RGB_GAMMA_CH0_CH1_CH2_SELECTED +}; + +struct vfe_cmd_rgb_gamma_config { + uint8_t enable; + enum VFE_RGB_GAMMA_TABLE_SELECT channelSelect; + int16_t table[VFE_GAMMA_TABLE_LENGTH]; +}; + +struct vfe_cmd_chroma_enhan_config { + uint8_t enable; + int16_t am; + int16_t ap; + int16_t bm; + int16_t bp; + int16_t cm; + int16_t cp; + int16_t dm; + int16_t dp; + int16_t kcr; + int16_t kcb; + int16_t RGBtoYConversionV0; + int16_t RGBtoYConversionV1; + int16_t RGBtoYConversionV2; + uint8_t RGBtoYConversionOffset; +}; + +struct vfe_cmd_chroma_suppression_config { + uint8_t enable; + uint8_t m1; + uint8_t m3; + uint8_t n1; + uint8_t n3; + uint8_t nn1; + uint8_t mm1; +}; + +struct vfe_cmd_asf_config { + uint8_t enable; + uint8_t smoothFilterEnabled; + uint8_t sharpMode; + uint8_t smoothCoefCenter; + uint8_t smoothCoefSurr; + uint8_t normalizeFactor; + uint8_t sharpK1; + uint8_t sharpK2; + uint8_t sharpThreshE1; + int8_t sharpThreshE2; + int8_t sharpThreshE3; + int8_t sharpThreshE4; + int8_t sharpThreshE5; + int8_t filter1Coefficients[9]; + int8_t filter2Coefficients[9]; + uint8_t cropEnable; + uint16_t cropFirstPixel; + uint16_t cropLastPixel; + uint16_t cropFirstLine; + uint16_t cropLastLine; +}; + +struct vfe_cmd_asf_update { + uint8_t enable; + uint8_t smoothFilterEnabled; + uint8_t sharpMode; + uint8_t smoothCoefCenter; + uint8_t smoothCoefSurr; + uint8_t normalizeFactor; + uint8_t sharpK1; + uint8_t sharpK2; + uint8_t sharpThreshE1; + int8_t sharpThreshE2; + int8_t sharpThreshE3; + int8_t sharpThreshE4; + int8_t sharpThreshE5; + int8_t filter1Coefficients[9]; + int8_t filter2Coefficients[9]; + uint8_t cropEnable; +}; + +enum VFE_TEST_GEN_SYNC_EDGE { + VFE_TEST_GEN_SYNC_EDGE_ActiveHigh, + VFE_TEST_GEN_SYNC_EDGE_ActiveLow +}; + +struct vfe_cmd_test_gen_start { + uint8_t pixelDataSelect; + uint8_t systematicDataSelect; + enum VFE_TEST_GEN_SYNC_EDGE hsyncEdge; + enum VFE_TEST_GEN_SYNC_EDGE vsyncEdge; + uint16_t numFrame; + enum VFE_RAW_PIXEL_DATA_SIZE pixelDataSize; + uint16_t imageWidth; + uint16_t imageHeight; + uint32_t startOfFrameOffset; + uint32_t endOfFrameNOffset; + uint16_t startOfLineOffset; + uint16_t endOfLineNOffset; + uint16_t hbi; + uint8_t vblEnable; + uint16_t vbl; + uint8_t startOfFrameDummyLine; + uint8_t endOfFrameDummyLine; + uint8_t unicolorBarEnable; + uint8_t colorBarsSplitEnable; + uint8_t unicolorBarSelect; + enum VFE_START_PIXEL_PATTERN colorBarsPixelPattern; + uint8_t colorBarsRotatePeriod; + uint16_t testGenRandomSeed; +}; + +struct vfe_cmd_bus_pm_start { + uint8_t output2YWrPmEnable; + uint8_t output2CbcrWrPmEnable; + uint8_t output1YWrPmEnable; + uint8_t output1CbcrWrPmEnable; +}; + +struct vfe_cmd_camif_frame_update { + struct vfe_cmds_camif_frame camifFrame; +}; + +struct vfe_cmd_sync_timer_setting { + uint8_t whichSyncTimer; + uint8_t operation; + uint8_t polarity; + uint16_t repeatCount; + uint16_t hsyncCount; + uint32_t pclkCount; + uint32_t outputDuration; +}; + +struct vfe_cmd_async_timer_setting { + uint8_t whichAsyncTimer; + uint8_t operation; + uint8_t polarity; + uint16_t repeatCount; + uint16_t inactiveCount; + uint32_t activeCount; +}; + +struct vfe_frame_skip_counts { + uint32_t totalFrameCount; + uint32_t output1Count; + uint32_t output2Count; +}; + +enum VFE_AXI_RD_UNPACK_HBI_SEL { + VFE_AXI_RD_HBI_32_CLOCK_CYCLES, + VFE_AXI_RD_HBI_64_CLOCK_CYCLES, + VFE_AXI_RD_HBI_128_CLOCK_CYCLES, + VFE_AXI_RD_HBI_256_CLOCK_CYCLES, + VFE_AXI_RD_HBI_512_CLOCK_CYCLES, + VFE_AXI_RD_HBI_1024_CLOCK_CYCLES, + VFE_AXI_RD_HBI_2048_CLOCK_CYCLES, + VFE_AXI_RD_HBI_4096_CLOCK_CYCLES +}; + +struct vfe_cmd_axi_input_config { + uint32_t fragAddr[4]; + uint8_t totalFragmentCount; + uint16_t ySize; + uint16_t xOffset; + uint16_t xSize; + uint16_t rowIncrement; + uint16_t numOfRows; + enum VFE_AXI_BURST_LENGTH burstLength; + uint8_t unpackPhase; + enum VFE_AXI_RD_UNPACK_HBI_SEL unpackHbi; + enum VFE_RAW_PIXEL_DATA_SIZE pixelSize; + uint8_t padRepeatCountLeft; + uint8_t padRepeatCountRight; + uint8_t padRepeatCountTop; + uint8_t padRepeatCountBottom; + uint8_t padLeftComponentSelectCycle0; + uint8_t padLeftComponentSelectCycle1; + uint8_t padLeftComponentSelectCycle2; + uint8_t padLeftComponentSelectCycle3; + uint8_t padLeftStopCycle0; + uint8_t padLeftStopCycle1; + uint8_t padLeftStopCycle2; + uint8_t padLeftStopCycle3; + uint8_t padRightComponentSelectCycle0; + uint8_t padRightComponentSelectCycle1; + uint8_t padRightComponentSelectCycle2; + uint8_t padRightComponentSelectCycle3; + uint8_t padRightStopCycle0; + uint8_t padRightStopCycle1; + uint8_t padRightStopCycle2; + uint8_t padRightStopCycle3; + uint8_t padTopLineCount; + uint8_t padBottomLineCount; +}; + +struct vfe_interrupt_status { + uint8_t camifErrorIrq; + uint8_t camifSofIrq; + uint8_t camifEolIrq; + uint8_t camifEofIrq; + uint8_t camifEpoch1Irq; + uint8_t camifEpoch2Irq; + uint8_t camifOverflowIrq; + uint8_t ceIrq; + uint8_t regUpdateIrq; + uint8_t resetAckIrq; + uint8_t encYPingpongIrq; + uint8_t encCbcrPingpongIrq; + uint8_t viewYPingpongIrq; + uint8_t viewCbcrPingpongIrq; + uint8_t rdPingpongIrq; + uint8_t afPingpongIrq; + uint8_t awbPingpongIrq; + uint8_t histPingpongIrq; + uint8_t encIrq; + uint8_t viewIrq; + uint8_t busOverflowIrq; + uint8_t afOverflowIrq; + uint8_t awbOverflowIrq; + uint8_t syncTimer0Irq; + uint8_t syncTimer1Irq; + uint8_t syncTimer2Irq; + uint8_t asyncTimer0Irq; + uint8_t asyncTimer1Irq; + uint8_t asyncTimer2Irq; + uint8_t asyncTimer3Irq; + uint8_t axiErrorIrq; + uint8_t violationIrq; + uint8_t anyErrorIrqs; + uint8_t anyOutput1PathIrqs; + uint8_t anyOutput2PathIrqs; + uint8_t anyOutputPathIrqs; + uint8_t anyAsyncTimerIrqs; + uint8_t anySyncTimerIrqs; + uint8_t anyIrqForActiveStatesOnly; +}; + +enum VFE_MESSAGE_ID { + VFE_MSG_ID_RESET_ACK, + VFE_MSG_ID_START_ACK, + VFE_MSG_ID_STOP_ACK, + VFE_MSG_ID_UPDATE_ACK, + VFE_MSG_ID_OUTPUT1, + VFE_MSG_ID_OUTPUT2, + VFE_MSG_ID_SNAPSHOT_DONE, + VFE_MSG_ID_STATS_AUTOFOCUS, + VFE_MSG_ID_STATS_WB_EXP, + VFE_MSG_ID_EPOCH1, + VFE_MSG_ID_EPOCH2, + VFE_MSG_ID_SYNC_TIMER0_DONE, + VFE_MSG_ID_SYNC_TIMER1_DONE, + VFE_MSG_ID_SYNC_TIMER2_DONE, + VFE_MSG_ID_ASYNC_TIMER0_DONE, + VFE_MSG_ID_ASYNC_TIMER1_DONE, + VFE_MSG_ID_ASYNC_TIMER2_DONE, + VFE_MSG_ID_ASYNC_TIMER3_DONE, + VFE_MSG_ID_AF_OVERFLOW, + VFE_MSG_ID_AWB_OVERFLOW, + VFE_MSG_ID_AXI_ERROR, + VFE_MSG_ID_CAMIF_OVERFLOW, + VFE_MSG_ID_VIOLATION, + VFE_MSG_ID_CAMIF_ERROR, + VFE_MSG_ID_BUS_OVERFLOW, +}; + +struct vfe_msg_stats_autofocus { + uint32_t afBuffer; + uint32_t frameCounter; +}; + +struct vfe_msg_stats_wb_exp { + uint32_t awbBuffer; + uint32_t frameCounter; +}; + +struct vfe_frame_bpc_info { + uint32_t greenDefectPixelCount; + uint32_t redBlueDefectPixelCount; +}; + +struct vfe_frame_asf_info { + uint32_t asfMaxEdge; + uint32_t asfHbiCount; +}; + +struct vfe_msg_camif_status { + uint8_t camifState; + uint32_t pixelCount; + uint32_t lineCount; +}; + +struct vfe_bus_pm_per_path { + uint32_t yWrPmStats0; + uint32_t yWrPmStats1; + uint32_t cbcrWrPmStats0; + uint32_t cbcrWrPmStats1; +}; + +struct vfe_bus_performance_monitor { + struct vfe_bus_pm_per_path encPathPmInfo; + struct vfe_bus_pm_per_path viewPathPmInfo; +}; + +struct vfe_irq_thread_msg { + uint32_t vfeIrqStatus; + uint32_t camifStatus; + uint32_t demosaicStatus; + uint32_t asfMaxEdge; + struct vfe_bus_performance_monitor pmInfo; +}; + +struct vfe_msg_output { + uint32_t yBuffer; + uint32_t cbcrBuffer; + struct vfe_frame_bpc_info bpcInfo; + struct vfe_frame_asf_info asfInfo; + uint32_t frameCounter; + struct vfe_bus_pm_per_path pmData; +}; + +struct vfe_message { + enum VFE_MESSAGE_ID _d; + union { + struct vfe_msg_output msgOutput1; + struct vfe_msg_output msgOutput2; + struct vfe_msg_stats_autofocus msgStatsAf; + struct vfe_msg_stats_wb_exp msgStatsWbExp; + struct vfe_msg_camif_status msgCamifError; + struct vfe_bus_performance_monitor msgBusOverflow; + } _u; +}; + +/* New one for 8k */ +struct msm_vfe_command_8k { + int32_t id; + uint16_t length; + void *value; +}; + +struct vfe_frame_extra { + struct vfe_frame_bpc_info bpcInfo; + struct vfe_frame_asf_info asfInfo; + uint32_t frameCounter; + struct vfe_bus_pm_per_path pmData; +}; +#endif /* __MSM_VFE8X_H__ */ diff --git a/trunk/drivers/staging/dream/camera/msm_vfe8x_proc.c b/trunk/drivers/staging/dream/camera/msm_vfe8x_proc.c new file mode 100644 index 000000000000..f80ef967ba87 --- /dev/null +++ b/trunk/drivers/staging/dream/camera/msm_vfe8x_proc.c @@ -0,0 +1,4003 @@ +/* +* Copyright (C) 2008-2009 QUALCOMM Incorporated. +*/ +#include +#include +#include +#include +#include +#include +#include +#include "msm_vfe8x_proc.h" +#include + +struct msm_vfe8x_ctrl { + /* bit 1:0 ENC_IRQ_MASK = 0x11: + * generate IRQ when both y and cbcr frame is ready. */ + + /* bit 1:0 VIEW_IRQ_MASK= 0x11: + * generate IRQ when both y and cbcr frame is ready. */ + struct vfe_irq_composite_mask_config vfeIrqCompositeMaskLocal; + struct vfe_module_enable vfeModuleEnableLocal; + struct vfe_camif_cfg_data vfeCamifConfigLocal; + struct vfe_interrupt_mask vfeImaskLocal; + struct vfe_stats_cmd_data vfeStatsCmdLocal; + struct vfe_bus_cfg_data vfeBusConfigLocal; + struct vfe_cmd_bus_pm_start vfeBusPmConfigLocal; + struct vfe_bus_cmd_data vfeBusCmdLocal; + enum vfe_interrupt_name vfeInterruptNameLocal; + uint32_t vfeLaBankSel; + struct vfe_gamma_lut_sel vfeGammaLutSel; + + boolean vfeStartAckPendingFlag; + boolean vfeStopAckPending; + boolean vfeResetAckPending; + boolean vfeUpdateAckPending; + + enum VFE_AXI_OUTPUT_MODE axiOutputMode; + enum VFE_START_OPERATION_MODE vfeOperationMode; + + uint32_t vfeSnapShotCount; + uint32_t vfeRequestedSnapShotCount; + boolean vfeStatsPingPongReloadFlag; + uint32_t vfeFrameId; + + struct vfe_cmd_frame_skip_config vfeFrameSkip; + uint32_t vfeFrameSkipPattern; + uint8_t vfeFrameSkipCount; + uint8_t vfeFrameSkipPeriod; + + boolean vfeTestGenStartFlag; + uint32_t vfeImaskPacked; + uint32_t vfeImaskCompositePacked; + enum VFE_RAW_PIXEL_DATA_SIZE axiInputDataSize; + struct vfe_irq_thread_msg vfeIrqThreadMsgLocal; + + struct vfe_output_path_combo viewPath; + struct vfe_output_path_combo encPath; + struct vfe_frame_skip_counts vfeDroppedFrameCounts; + struct vfe_stats_control afStatsControl; + struct vfe_stats_control awbStatsControl; + + enum VFE_STATE vstate; + + spinlock_t ack_lock; + spinlock_t state_lock; + spinlock_t io_lock; + + struct msm_vfe_callback *resp; + uint32_t extlen; + void *extdata; + + spinlock_t tasklet_lock; + struct list_head tasklet_q; + + int vfeirq; + void __iomem *vfebase; + + void *syncdata; +}; +static struct msm_vfe8x_ctrl *ctrl; +static irqreturn_t vfe_parse_irq(int irq_num, void *data); + +struct isr_queue_cmd { + struct list_head list; + struct vfe_interrupt_status vfeInterruptStatus; + struct vfe_frame_asf_info vfeAsfFrameInfo; + struct vfe_frame_bpc_info vfeBpcFrameInfo; + struct vfe_msg_camif_status vfeCamifStatusLocal; + struct vfe_bus_performance_monitor vfePmData; +}; + +static void vfe_prog_hw(uint8_t *hwreg, + uint32_t *inptr, uint32_t regcnt) +{ + /* unsigned long flags; */ + uint32_t i; + uint32_t *p; + + /* @todo This is causing issues, need further investigate */ + /* spin_lock_irqsave(&ctrl->io_lock, flags); */ + + p = (uint32_t *)(hwreg); + for (i = 0; i < (regcnt >> 2); i++) + writel(*inptr++, p++); + /* *p++ = *inptr++; */ + + /* spin_unlock_irqrestore(&ctrl->io_lock, flags); */ +} + +static void vfe_read_reg_values(uint8_t *hwreg, + uint32_t *dest, uint32_t count) +{ + /* unsigned long flags; */ + uint32_t *temp; + uint32_t i; + + /* @todo This is causing issues, need further investigate */ + /* spin_lock_irqsave(&ctrl->io_lock, flags); */ + + temp = (uint32_t *)(hwreg); + for (i = 0; i < count; i++) + *dest++ = *temp++; + + /* spin_unlock_irqrestore(&ctrl->io_lock, flags); */ +} + +static struct vfe_irqenable vfe_read_irq_mask(void) +{ + /* unsigned long flags; */ + uint32_t *temp; + struct vfe_irqenable rc; + + memset(&rc, 0, sizeof(rc)); + + /* @todo This is causing issues, need further investigate */ + /* spin_lock_irqsave(&ctrl->io_lock, flags); */ + temp = (uint32_t *)(ctrl->vfebase + VFE_IRQ_MASK); + + rc = *((struct vfe_irqenable *)temp); + /* spin_unlock_irqrestore(&ctrl->io_lock, flags); */ + + return rc; +} + +static void +vfe_set_bus_pipo_addr(struct vfe_output_path_combo *vpath, + struct vfe_output_path_combo *epath) +{ + vpath->yPath.hwRegPingAddress = (uint8_t *) + (ctrl->vfebase + VFE_BUS_VIEW_Y_WR_PING_ADDR); + vpath->yPath.hwRegPongAddress = (uint8_t *) + (ctrl->vfebase + VFE_BUS_VIEW_Y_WR_PONG_ADDR); + vpath->cbcrPath.hwRegPingAddress = (uint8_t *) + (ctrl->vfebase + VFE_BUS_VIEW_CBCR_WR_PING_ADDR); + vpath->cbcrPath.hwRegPongAddress = (uint8_t *) + (ctrl->vfebase + VFE_BUS_VIEW_CBCR_WR_PONG_ADDR); + + epath->yPath.hwRegPingAddress = (uint8_t *) + (ctrl->vfebase + VFE_BUS_ENC_Y_WR_PING_ADDR); + epath->yPath.hwRegPongAddress = (uint8_t *) + (ctrl->vfebase + VFE_BUS_ENC_Y_WR_PONG_ADDR); + epath->cbcrPath.hwRegPingAddress = (uint8_t *) + (ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PING_ADDR); + epath->cbcrPath.hwRegPongAddress = (uint8_t *) + (ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PONG_ADDR); +} + +static void vfe_axi_output(struct vfe_cmd_axi_output_config *in, + struct vfe_output_path_combo *out1, + struct vfe_output_path_combo *out2, uint16_t out) +{ + struct vfe_axi_out_cfg cmd; + + uint16_t temp; + uint32_t burstLength; + + /* force it to burst length 4, hardware does not support it. */ + burstLength = 1; + + /* AXI Output 2 Y Configuration*/ + /* VFE_BUS_ENC_Y_WR_PING_ADDR */ + cmd.out2YPingAddr = out2->yPath.addressBuffer[0]; + + /* VFE_BUS_ENC_Y_WR_PONG_ADDR */ + cmd.out2YPongAddr = out2->yPath.addressBuffer[1]; + + /* VFE_BUS_ENC_Y_WR_IMAGE_SIZE */ + cmd.out2YImageHeight = in->output2.outputY.imageHeight; + /* convert the image width and row increment to be in + * unit of 64bit (8 bytes) */ + temp = (in->output2.outputY.imageWidth + (out - 1)) / + out; + cmd.out2YImageWidthin64bit = temp; + + /* VFE_BUS_ENC_Y_WR_BUFFER_CFG */ + cmd.out2YBurstLength = burstLength; + cmd.out2YNumRows = in->output2.outputY.outRowCount; + temp = (in->output2.outputY.outRowIncrement + (out - 1)) / + out; + cmd.out2YRowIncrementIn64bit = temp; + + /* AXI Output 2 Cbcr Configuration*/ + /* VFE_BUS_ENC_Cbcr_WR_PING_ADDR */ + cmd.out2CbcrPingAddr = out2->cbcrPath.addressBuffer[0]; + + /* VFE_BUS_ENC_Cbcr_WR_PONG_ADDR */ + cmd.out2CbcrPongAddr = out2->cbcrPath.addressBuffer[1]; + + /* VFE_BUS_ENC_Cbcr_WR_IMAGE_SIZE */ + cmd.out2CbcrImageHeight = in->output2.outputCbcr.imageHeight; + temp = (in->output2.outputCbcr.imageWidth + (out - 1)) / + out; + cmd.out2CbcrImageWidthIn64bit = temp; + + /* VFE_BUS_ENC_Cbcr_WR_BUFFER_CFG */ + cmd.out2CbcrBurstLength = burstLength; + cmd.out2CbcrNumRows = in->output2.outputCbcr.outRowCount; + temp = (in->output2.outputCbcr.outRowIncrement + (out - 1)) / + out; + cmd.out2CbcrRowIncrementIn64bit = temp; + + /* AXI Output 1 Y Configuration */ + /* VFE_BUS_VIEW_Y_WR_PING_ADDR */ + cmd.out1YPingAddr = out1->yPath.addressBuffer[0]; + + /* VFE_BUS_VIEW_Y_WR_PONG_ADDR */ + cmd.out1YPongAddr = out1->yPath.addressBuffer[1]; + + /* VFE_BUS_VIEW_Y_WR_IMAGE_SIZE */ + cmd.out1YImageHeight = in->output1.outputY.imageHeight; + temp = (in->output1.outputY.imageWidth + (out - 1)) / + out; + cmd.out1YImageWidthin64bit = temp; + + /* VFE_BUS_VIEW_Y_WR_BUFFER_CFG */ + cmd.out1YBurstLength = burstLength; + cmd.out1YNumRows = in->output1.outputY.outRowCount; + + temp = + (in->output1.outputY.outRowIncrement + + (out - 1)) / out; + cmd.out1YRowIncrementIn64bit = temp; + + /* AXI Output 1 Cbcr Configuration*/ + cmd.out1CbcrPingAddr = out1->cbcrPath.addressBuffer[0]; + + /* VFE_BUS_VIEW_Cbcr_WR_PONG_ADDR */ + cmd.out1CbcrPongAddr = + out1->cbcrPath.addressBuffer[1]; + + /* VFE_BUS_VIEW_Cbcr_WR_IMAGE_SIZE */ + cmd.out1CbcrImageHeight = in->output1.outputCbcr.imageHeight; + temp = (in->output1.outputCbcr.imageWidth + + (out - 1)) / out; + cmd.out1CbcrImageWidthIn64bit = temp; + + cmd.out1CbcrBurstLength = burstLength; + cmd.out1CbcrNumRows = in->output1.outputCbcr.outRowCount; + temp = + (in->output1.outputCbcr.outRowIncrement + + (out - 1)) / out; + + cmd.out1CbcrRowIncrementIn64bit = temp; + + vfe_prog_hw(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PING_ADDR, + (uint32_t *)&cmd, sizeof(cmd)); +} + +static void vfe_reg_bus_cfg(struct vfe_bus_cfg_data *in) +{ + struct vfe_axi_bus_cfg cmd; + + cmd.stripeRdPathEn = in->stripeRdPathEn; + cmd.encYWrPathEn = in->encYWrPathEn; + cmd.encCbcrWrPathEn = in->encCbcrWrPathEn; + cmd.viewYWrPathEn = in->viewYWrPathEn; + cmd.viewCbcrWrPathEn = in->viewCbcrWrPathEn; + cmd.rawPixelDataSize = (uint32_t)in->rawPixelDataSize; + cmd.rawWritePathSelect = (uint32_t)in->rawWritePathSelect; + + /* program vfe_bus_cfg */ + writel(*((uint32_t *)&cmd), ctrl->vfebase + VFE_BUS_CFG); +} + +static void vfe_reg_camif_config(struct vfe_camif_cfg_data *in) +{ + struct VFE_CAMIFConfigType cfg; + + memset(&cfg, 0, sizeof(cfg)); + + cfg.VSyncEdge = + in->camifCfgFromCmd.vSyncEdge; + + cfg.HSyncEdge = + in->camifCfgFromCmd.hSyncEdge; + + cfg.syncMode = + in->camifCfgFromCmd.syncMode; + + cfg.vfeSubsampleEnable = + in->camifCfgFromCmd.vfeSubSampleEnable; + + cfg.busSubsampleEnable = + in->camifCfgFromCmd.busSubSampleEnable; + + cfg.camif2vfeEnable = + in->camif2OutputEnable; + + cfg.camif2busEnable = + in->camif2BusEnable; + + cfg.irqSubsampleEnable = + in->camifCfgFromCmd.irqSubSampleEnable; + + cfg.binningEnable = + in->camifCfgFromCmd.binningEnable; + + cfg.misrEnable = + in->camifCfgFromCmd.misrEnable; + + /* program camif_config */ + writel(*((uint32_t *)&cfg), ctrl->vfebase + CAMIF_CONFIG); +} + +static void vfe_reg_bus_cmd(struct vfe_bus_cmd_data *in) +{ + struct vfe_buscmd cmd; + memset(&cmd, 0, sizeof(cmd)); + + cmd.stripeReload = in->stripeReload; + cmd.busPingpongReload = in->busPingpongReload; + cmd.statsPingpongReload = in->statsPingpongReload; + + writel(*((uint32_t *)&cmd), ctrl->vfebase + VFE_BUS_CMD); + + CDBG("bus command = 0x%x\n", (*((uint32_t *)&cmd))); + + /* this is needed, as the control bits are pulse based. + * Don't want to reload bus pingpong again. */ + in->busPingpongReload = 0; + in->statsPingpongReload = 0; + in->stripeReload = 0; +} + +static void vfe_reg_module_cfg(struct vfe_module_enable *in) +{ + struct vfe_mod_enable ena; + + memset(&ena, 0, sizeof(ena)); + + ena.blackLevelCorrectionEnable = in->blackLevelCorrectionEnable; + ena.lensRollOffEnable = in->lensRollOffEnable; + ena.demuxEnable = in->demuxEnable; + ena.chromaUpsampleEnable = in->chromaUpsampleEnable; + ena.demosaicEnable = in->demosaicEnable; + ena.statsEnable = in->statsEnable; + ena.cropEnable = in->cropEnable; + ena.mainScalerEnable = in->mainScalerEnable; + ena.whiteBalanceEnable = in->whiteBalanceEnable; + ena.colorCorrectionEnable = in->colorCorrectionEnable; + ena.yHistEnable = in->yHistEnable; + ena.skinToneEnable = in->skinToneEnable; + ena.lumaAdaptationEnable = in->lumaAdaptationEnable; + ena.rgbLUTEnable = in->rgbLUTEnable; + ena.chromaEnhanEnable = in->chromaEnhanEnable; + ena.asfEnable = in->asfEnable; + ena.chromaSuppressionEnable = in->chromaSuppressionEnable; + ena.chromaSubsampleEnable = in->chromaSubsampleEnable; + ena.scaler2YEnable = in->scaler2YEnable; + ena.scaler2CbcrEnable = in->scaler2CbcrEnable; + + writel(*((uint32_t *)&ena), ctrl->vfebase + VFE_MODULE_CFG); +} + +static void vfe_program_dmi_cfg(enum VFE_DMI_RAM_SEL bankSel) +{ + /* set bit 8 for auto increment. */ + uint32_t value = (uint32_t) ctrl->vfebase + VFE_DMI_CFG_DEFAULT; + + value += (uint32_t)bankSel; + /* CDBG("dmi cfg input bank is 0x%x\n", bankSel); */ + + writel(value, ctrl->vfebase + VFE_DMI_CFG); + writel(0, ctrl->vfebase + VFE_DMI_ADDR); +} + +static void vfe_write_lens_roll_off_table( + struct vfe_cmd_roll_off_config *in) +{ + uint16_t i; + uint32_t data; + + uint16_t *initGr = in->initTableGr; + uint16_t *initGb = in->initTableGb; + uint16_t *initB = in->initTableB; + uint16_t *initR = in->initTableR; + + int16_t *pDeltaGr = in->deltaTableGr; + int16_t *pDeltaGb = in->deltaTableGb; + int16_t *pDeltaB = in->deltaTableB; + int16_t *pDeltaR = in->deltaTableR; + + vfe_program_dmi_cfg(ROLLOFF_RAM); + + /* first pack and write init table */ + for (i = 0; i < VFE_ROLL_OFF_INIT_TABLE_SIZE; i++) { + data = (((uint32_t)(*initR)) & 0x0000FFFF) | + (((uint32_t)(*initGr)) << 16); + initR++; + initGr++; + + writel(data, ctrl->vfebase + VFE_DMI_DATA_LO); + + data = (((uint32_t)(*initB)) & 0x0000FFFF) | + (((uint32_t)(*initGr))<<16); + initB++; + initGb++; + + writel(data, ctrl->vfebase + VFE_DMI_DATA_LO); + } + + /* there are gaps between the init table and delta table, + * set the offset for delta table. */ + writel(LENS_ROLL_OFF_DELTA_TABLE_OFFSET, + ctrl->vfebase + VFE_DMI_ADDR); + + /* pack and write delta table */ + for (i = 0; i < VFE_ROLL_OFF_DELTA_TABLE_SIZE; i++) { + data = (((int32_t)(*pDeltaR)) & 0x0000FFFF) | + (((int32_t)(*pDeltaGr))<<16); + pDeltaR++; + pDeltaGr++; + + writel(data, ctrl->vfebase + VFE_DMI_DATA_LO); + + data = (((int32_t)(*pDeltaB)) & 0x0000FFFF) | + (((int32_t)(*pDeltaGb))<<16); + pDeltaB++; + pDeltaGb++; + + writel(data, ctrl->vfebase + VFE_DMI_DATA_LO); + } + + /* After DMI transfer, to make it safe, need to set the + * DMI_CFG to unselect any SRAM + */ + /* unselect the SRAM Bank. */ + writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG); +} + +static void vfe_set_default_reg_values(void) +{ + writel(0x800080, ctrl->vfebase + VFE_DEMUX_GAIN_0); + writel(0x800080, ctrl->vfebase + VFE_DEMUX_GAIN_1); + writel(0xFFFFF, ctrl->vfebase + VFE_CGC_OVERRIDE); + + /* default frame drop period and pattern */ + writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG); + writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG); + writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN); + writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_PATTERN); + writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_CFG); + writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_CFG); + writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN); + writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_PATTERN); + writel(0, ctrl->vfebase + VFE_CLAMP_MIN_CFG); + writel(0xFFFFFF, ctrl->vfebase + VFE_CLAMP_MAX_CFG); +} + +static void vfe_config_demux(uint32_t period, uint32_t even, uint32_t odd) +{ + writel(period, ctrl->vfebase + VFE_DEMUX_CFG); + writel(even, ctrl->vfebase + VFE_DEMUX_EVEN_CFG); + writel(odd, ctrl->vfebase + VFE_DEMUX_ODD_CFG); +} + +static void vfe_pm_stop(void) +{ + writel(VFE_PERFORMANCE_MONITOR_STOP, ctrl->vfebase + VFE_BUS_PM_CMD); +} + +static void vfe_program_bus_rd_irq_en(uint32_t value) +{ + writel(value, ctrl->vfebase + VFE_BUS_PINGPONG_IRQ_EN); +} + +static void vfe_camif_go(void) +{ + writel(CAMIF_COMMAND_START, ctrl->vfebase + CAMIF_COMMAND); +} + +static void vfe_camif_stop_immediately(void) +{ + writel(CAMIF_COMMAND_STOP_IMMEDIATELY, ctrl->vfebase + CAMIF_COMMAND); + writel(0, ctrl->vfebase + VFE_CGC_OVERRIDE); +} + +static void vfe_program_reg_update_cmd(uint32_t value) +{ + writel(value, ctrl->vfebase + VFE_REG_UPDATE_CMD); +} + +static void vfe_program_bus_cmd(uint32_t value) +{ + writel(value, ctrl->vfebase + VFE_BUS_CMD); +} + +static void vfe_program_global_reset_cmd(uint32_t value) +{ + writel(value, ctrl->vfebase + VFE_GLOBAL_RESET_CMD); +} + +static void vfe_program_axi_cmd(uint32_t value) +{ + writel(value, ctrl->vfebase + VFE_AXI_CMD); +} + +static void vfe_program_irq_composite_mask(uint32_t value) +{ + writel(value, ctrl->vfebase + VFE_IRQ_COMPOSITE_MASK); +} + +static inline void vfe_program_irq_mask(uint32_t value) +{ + writel(value, ctrl->vfebase + VFE_IRQ_MASK); +} + +static void vfe_program_chroma_upsample_cfg(uint32_t value) +{ + writel(value, ctrl->vfebase + VFE_CHROMA_UPSAMPLE_CFG); +} + +static uint32_t vfe_read_axi_status(void) +{ + return readl(ctrl->vfebase + VFE_AXI_STATUS); +} + +static uint32_t vfe_read_pm_status_in_raw_capture(void) +{ + return readl(ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PM_STATS_1); +} + +static void +vfe_set_stats_pingpong_address(struct vfe_stats_control *afControl, + struct vfe_stats_control *awbControl) +{ + afControl->hwRegPingAddress = (uint8_t *) + (ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR); + afControl->hwRegPongAddress = (uint8_t *) + (ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR); + + awbControl->hwRegPingAddress = (uint8_t *) + (ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR); + awbControl->hwRegPongAddress = (uint8_t *) + (ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR); +} + +static uint32_t vfe_read_camif_status(void) +{ + return readl(ctrl->vfebase + CAMIF_STATUS); +} + +static void vfe_program_lut_bank_sel(struct vfe_gamma_lut_sel *in) +{ + struct VFE_GammaLutSelect_ConfigCmdType cmd; + + memset(&cmd, 0, sizeof(cmd)); + + cmd.ch0BankSelect = in->ch0BankSelect; + cmd.ch1BankSelect = in->ch1BankSelect; + cmd.ch2BankSelect = in->ch2BankSelect; + CDBG("VFE gamma lut bank selection is 0x%x\n", *((uint32_t *)&cmd)); + vfe_prog_hw(ctrl->vfebase + VFE_LUT_BANK_SEL, + (uint32_t *)&cmd, sizeof(cmd)); +} + +static void vfe_program_stats_cmd(struct vfe_stats_cmd_data *in) +{ + struct VFE_StatsCmdType stats; + memset(&stats, 0, sizeof(stats)); + + stats.autoFocusEnable = in->autoFocusEnable; + stats.axwEnable = in->axwEnable; + stats.histEnable = in->histEnable; + stats.clearHistEnable = in->clearHistEnable; + stats.histAutoClearEnable = in->histAutoClearEnable; + stats.colorConversionEnable = in->colorConversionEnable; + + writel(*((uint32_t *)&stats), ctrl->vfebase + VFE_STATS_CMD); +} + +static void vfe_pm_start(struct vfe_cmd_bus_pm_start *in) +{ + struct VFE_Bus_Pm_ConfigCmdType cmd; + memset(&cmd, 0, sizeof(struct VFE_Bus_Pm_ConfigCmdType)); + + cmd.output2YWrPmEnable = in->output2YWrPmEnable; + cmd.output2CbcrWrPmEnable = in->output2CbcrWrPmEnable; + cmd.output1YWrPmEnable = in->output1YWrPmEnable; + cmd.output1CbcrWrPmEnable = in->output1CbcrWrPmEnable; + + vfe_prog_hw(ctrl->vfebase + VFE_BUS_PM_CFG, + (uint32_t *)&cmd, sizeof(cmd)); +} + +static void vfe_8k_pm_start(struct vfe_cmd_bus_pm_start *in) +{ + in->output1CbcrWrPmEnable = ctrl->vfeBusConfigLocal.viewCbcrWrPathEn; + in->output1YWrPmEnable = ctrl->vfeBusConfigLocal.viewYWrPathEn; + in->output2CbcrWrPmEnable = ctrl->vfeBusConfigLocal.encCbcrWrPathEn; + in->output2YWrPmEnable = ctrl->vfeBusConfigLocal.encYWrPathEn; + + if (in->output1CbcrWrPmEnable || in->output1YWrPmEnable) + ctrl->viewPath.pmEnabled = TRUE; + + if (in->output2CbcrWrPmEnable || in->output2YWrPmEnable) + ctrl->encPath.pmEnabled = TRUE; + + vfe_pm_start(in); + + writel(VFE_PERFORMANCE_MONITOR_GO, ctrl->vfebase + VFE_BUS_PM_CMD); +} + +static uint32_t vfe_irq_pack(struct vfe_interrupt_mask data) +{ + struct vfe_irqenable packedData; + + memset(&packedData, 0, sizeof(packedData)); + + packedData.camifErrorIrq = data.camifErrorIrq; + packedData.camifSofIrq = data.camifSofIrq; + packedData.camifEolIrq = data.camifEolIrq; + packedData.camifEofIrq = data.camifEofIrq; + packedData.camifEpoch1Irq = data.camifEpoch1Irq; + packedData.camifEpoch2Irq = data.camifEpoch2Irq; + packedData.camifOverflowIrq = data.camifOverflowIrq; + packedData.ceIrq = data.ceIrq; + packedData.regUpdateIrq = data.regUpdateIrq; + packedData.resetAckIrq = data.resetAckIrq; + packedData.encYPingpongIrq = data.encYPingpongIrq; + packedData.encCbcrPingpongIrq = data.encCbcrPingpongIrq; + packedData.viewYPingpongIrq = data.viewYPingpongIrq; + packedData.viewCbcrPingpongIrq = data.viewCbcrPingpongIrq; + packedData.rdPingpongIrq = data.rdPingpongIrq; + packedData.afPingpongIrq = data.afPingpongIrq; + packedData.awbPingpongIrq = data.awbPingpongIrq; + packedData.histPingpongIrq = data.histPingpongIrq; + packedData.encIrq = data.encIrq; + packedData.viewIrq = data.viewIrq; + packedData.busOverflowIrq = data.busOverflowIrq; + packedData.afOverflowIrq = data.afOverflowIrq; + packedData.awbOverflowIrq = data.awbOverflowIrq; + packedData.syncTimer0Irq = data.syncTimer0Irq; + packedData.syncTimer1Irq = data.syncTimer1Irq; + packedData.syncTimer2Irq = data.syncTimer2Irq; + packedData.asyncTimer0Irq = data.asyncTimer0Irq; + packedData.asyncTimer1Irq = data.asyncTimer1Irq; + packedData.asyncTimer2Irq = data.asyncTimer2Irq; + packedData.asyncTimer3Irq = data.asyncTimer3Irq; + packedData.axiErrorIrq = data.axiErrorIrq; + packedData.violationIrq = data.violationIrq; + + return *((uint32_t *)&packedData); +} + +static uint32_t +vfe_irq_composite_pack(struct vfe_irq_composite_mask_config data) +{ + struct VFE_Irq_Composite_MaskType packedData; + + memset(&packedData, 0, sizeof(packedData)); + + packedData.encIrqComMaskBits = data.encIrqComMask; + packedData.viewIrqComMaskBits = data.viewIrqComMask; + packedData.ceDoneSelBits = data.ceDoneSel; + + return *((uint32_t *)&packedData); +} + +static void vfe_addr_convert(struct msm_vfe_phy_info *pinfo, + enum vfe_resp_msg type, void *data, void **ext, int32_t *elen) +{ + switch (type) { + case VFE_MSG_OUTPUT1: { + pinfo->y_phy = + ((struct vfe_message *)data)->_u.msgOutput1.yBuffer; + pinfo->cbcr_phy = + ((struct vfe_message *)data)->_u.msgOutput1.cbcrBuffer; + + ((struct vfe_frame_extra *)ctrl->extdata)->bpcInfo = + ((struct vfe_message *)data)->_u.msgOutput1.bpcInfo; + + ((struct vfe_frame_extra *)ctrl->extdata)->asfInfo = + ((struct vfe_message *)data)->_u.msgOutput1.asfInfo; + + ((struct vfe_frame_extra *)ctrl->extdata)->frameCounter = + ((struct vfe_message *)data)->_u.msgOutput1.frameCounter; + + ((struct vfe_frame_extra *)ctrl->extdata)->pmData = + ((struct vfe_message *)data)->_u.msgOutput1.pmData; + + *ext = ctrl->extdata; + *elen = ctrl->extlen; + } + break; + + case VFE_MSG_OUTPUT2: { + pinfo->y_phy = + ((struct vfe_message *)data)->_u.msgOutput2.yBuffer; + pinfo->cbcr_phy = + ((struct vfe_message *)data)->_u.msgOutput2.cbcrBuffer; + + CDBG("vfe_addr_convert, pinfo->y_phy = 0x%x\n", pinfo->y_phy); + CDBG("vfe_addr_convert, pinfo->cbcr_phy = 0x%x\n", + pinfo->cbcr_phy); + + ((struct vfe_frame_extra *)ctrl->extdata)->bpcInfo = + ((struct vfe_message *)data)->_u.msgOutput2.bpcInfo; + + ((struct vfe_frame_extra *)ctrl->extdata)->asfInfo = + ((struct vfe_message *)data)->_u.msgOutput2.asfInfo; + + ((struct vfe_frame_extra *)ctrl->extdata)->frameCounter = + ((struct vfe_message *)data)->_u.msgOutput2.frameCounter; + + ((struct vfe_frame_extra *)ctrl->extdata)->pmData = + ((struct vfe_message *)data)->_u.msgOutput2.pmData; + + *ext = ctrl->extdata; + *elen = ctrl->extlen; + } + break; + + case VFE_MSG_STATS_AF: + pinfo->sbuf_phy = + ((struct vfe_message *)data)->_u.msgStatsAf.afBuffer; + break; + + case VFE_MSG_STATS_WE: + pinfo->sbuf_phy = + ((struct vfe_message *)data)->_u.msgStatsWbExp.awbBuffer; + break; + + default: + break; + } /* switch */ +} + +static void +vfe_proc_ops(enum VFE_MESSAGE_ID id, void *msg, size_t len) +{ + struct msm_vfe_resp *rp; + + /* In 8k, OUTPUT1 & OUTPUT2 messages arrive before + * SNAPSHOT_DONE. We don't send such messages to user */ + + CDBG("ctrl->vfeOperationMode = %d, msgId = %d\n", + ctrl->vfeOperationMode, id); + + if ((ctrl->vfeOperationMode == VFE_START_OPERATION_MODE_SNAPSHOT) && + (id == VFE_MSG_ID_OUTPUT1 || id == VFE_MSG_ID_OUTPUT2)) { + return; + } + + rp = ctrl->resp->vfe_alloc(sizeof(struct msm_vfe_resp), ctrl->syncdata); + if (!rp) { + CDBG("rp: cannot allocate buffer\n"); + return; + } + + CDBG("vfe_proc_ops, msgId = %d\n", id); + + rp->evt_msg.type = MSM_CAMERA_MSG; + rp->evt_msg.msg_id = id; + rp->evt_msg.len = len; + rp->evt_msg.data = msg; + + switch (rp->evt_msg.msg_id) { + case VFE_MSG_ID_SNAPSHOT_DONE: + rp->type = VFE_MSG_SNAPSHOT; + break; + + case VFE_MSG_ID_OUTPUT1: + rp->type = VFE_MSG_OUTPUT1; + vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT1, + rp->evt_msg.data, &(rp->extdata), + &(rp->extlen)); + break; + + case VFE_MSG_ID_OUTPUT2: + rp->type = VFE_MSG_OUTPUT2; + vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT2, + rp->evt_msg.data, &(rp->extdata), + &(rp->extlen)); + break; + + case VFE_MSG_ID_STATS_AUTOFOCUS: + rp->type = VFE_MSG_STATS_AF; + vfe_addr_convert(&(rp->phy), VFE_MSG_STATS_AF, + rp->evt_msg.data, NULL, NULL); + break; + + case VFE_MSG_ID_STATS_WB_EXP: + rp->type = VFE_MSG_STATS_WE; + vfe_addr_convert(&(rp->phy), VFE_MSG_STATS_WE, + rp->evt_msg.data, NULL, NULL); + break; + + default: + rp->type = VFE_MSG_GENERAL; + break; + } + + ctrl->resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG, ctrl->syncdata); +} + +static void vfe_send_msg_no_payload(enum VFE_MESSAGE_ID id) +{ + struct vfe_message *msg; + + msg = kzalloc(sizeof(*msg), GFP_ATOMIC); + if (!msg) + return; + + msg->_d = id; + vfe_proc_ops(id, msg, 0); +} + +static void vfe_send_bus_overflow_msg(void) +{ + struct vfe_message *msg; + msg = + kzalloc(sizeof(struct vfe_message), GFP_ATOMIC); + if (!msg) + return; + + msg->_d = VFE_MSG_ID_BUS_OVERFLOW; +#if 0 + memcpy(&(msg->_u.msgBusOverflow), + &ctrl->vfePmData, sizeof(ctrl->vfePmData)); +#endif + + vfe_proc_ops(VFE_MSG_ID_BUS_OVERFLOW, + msg, sizeof(struct vfe_message)); +} + +static void vfe_send_camif_error_msg(void) +{ +#if 0 + struct vfe_message *msg; + msg = + kzalloc(sizeof(struct vfe_message), GFP_ATOMIC); + if (!msg) + return; + + msg->_d = VFE_MSG_ID_CAMIF_ERROR; + memcpy(&(msg->_u.msgCamifError), + &ctrl->vfeCamifStatusLocal, sizeof(ctrl->vfeCamifStatusLocal)); + + vfe_proc_ops(VFE_MSG_ID_CAMIF_ERROR, + msg, sizeof(struct vfe_message)); +#endif +} + +static void vfe_process_error_irq( + struct vfe_interrupt_status *irqstatus) +{ + /* all possible error irq. Note error irqs are not enabled, it is + * checked only when other interrupts are present. */ + if (irqstatus->afOverflowIrq) + vfe_send_msg_no_payload(VFE_MSG_ID_AF_OVERFLOW); + + if (irqstatus->awbOverflowIrq) + vfe_send_msg_no_payload(VFE_MSG_ID_AWB_OVERFLOW); + + if (irqstatus->axiErrorIrq) + vfe_send_msg_no_payload(VFE_MSG_ID_AXI_ERROR); + + if (irqstatus->busOverflowIrq) + vfe_send_bus_overflow_msg(); + + if (irqstatus->camifErrorIrq) + vfe_send_camif_error_msg(); + + if (irqstatus->camifOverflowIrq) + vfe_send_msg_no_payload(VFE_MSG_ID_CAMIF_OVERFLOW); + + if (irqstatus->violationIrq) + ; +} + +static void vfe_process_camif_sof_irq(void) +{ + /* increment the frame id number. */ + ctrl->vfeFrameId++; + + CDBG("camif_sof_irq, frameId = %d\n", + ctrl->vfeFrameId); + + /* In snapshot mode, if frame skip is programmed, + * need to check it accordingly to stop camif at + * correct frame boundary. For the dropped frames, + * there won't be any output path irqs, but there is + * still SOF irq, which can help us determine when + * to stop the camif. + */ + if (ctrl->vfeOperationMode) { + if ((1 << ctrl->vfeFrameSkipCount) & + ctrl->vfeFrameSkipPattern) { + + ctrl->vfeSnapShotCount--; + if (ctrl->vfeSnapShotCount == 0) + /* terminate vfe pipeline at frame boundary. */ + writel(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY, + ctrl->vfebase + CAMIF_COMMAND); + } + + /* update frame skip counter for bit checking. */ + ctrl->vfeFrameSkipCount++; + if (ctrl->vfeFrameSkipCount == + (ctrl->vfeFrameSkipPeriod + 1)) + ctrl->vfeFrameSkipCount = 0; + } +} + +static int vfe_get_af_pingpong_status(void) +{ + uint32_t busPingPongStatus; + int rc = 0; + + busPingPongStatus = + readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS); + + if ((busPingPongStatus & VFE_AF_PINGPONG_STATUS_BIT) == 0) + return -EFAULT; + + return rc; +} + +static uint32_t vfe_read_af_buf_addr(boolean pipo) +{ + if (pipo == FALSE) + return readl(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR); + else + return readl(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR); +} + +static void +vfe_update_af_buf_addr(boolean pipo, uint32_t addr) +{ + if (pipo == FALSE) + writel(addr, ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR); + else + writel(addr, ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR); +} + +static void +vfe_send_af_stats_msg(uint32_t afBufAddress) +{ + /* unsigned long flags; */ + struct vfe_message *msg; + msg = + kzalloc(sizeof(struct vfe_message), GFP_ATOMIC); + if (!msg) + return; + + /* fill message with right content. */ + /* @todo This is causing issues, need further investigate */ + /* spin_lock_irqsave(&ctrl->state_lock, flags); */ + if (ctrl->vstate != VFE_STATE_ACTIVE) { + kfree(msg); + goto af_stats_done; + } + + msg->_d = VFE_MSG_ID_STATS_AUTOFOCUS; + msg->_u.msgStatsAf.afBuffer = afBufAddress; + msg->_u.msgStatsAf.frameCounter = ctrl->vfeFrameId; + + vfe_proc_ops(VFE_MSG_ID_STATS_AUTOFOCUS, + msg, sizeof(struct vfe_message)); + + ctrl->afStatsControl.ackPending = TRUE; + +af_stats_done: + /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */ + return; +} + +static void vfe_process_stats_af_irq(void) +{ + boolean bufferAvailable; + + if (!(ctrl->afStatsControl.ackPending)) { + + /* read hardware status. */ + ctrl->afStatsControl.pingPongStatus = + vfe_get_af_pingpong_status(); + + bufferAvailable = + (ctrl->afStatsControl.pingPongStatus) ^ 1; + + ctrl->afStatsControl.bufToRender = + vfe_read_af_buf_addr(bufferAvailable); + + /* update the same buffer address (ping or pong) */ + vfe_update_af_buf_addr(bufferAvailable, + ctrl->afStatsControl.nextFrameAddrBuf); + + vfe_send_af_stats_msg(ctrl->afStatsControl.bufToRender); + } else + ctrl->afStatsControl.droppedStatsFrameCount++; +} + +static boolean vfe_get_awb_pingpong_status(void) +{ + uint32_t busPingPongStatus; + + busPingPongStatus = + readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS); + + if ((busPingPongStatus & VFE_AWB_PINGPONG_STATUS_BIT) == 0) + return FALSE; + + return TRUE; +} + +static uint32_t +vfe_read_awb_buf_addr(boolean pingpong) +{ + if (pingpong == FALSE) + return readl(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR); + else + return readl(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR); +} + +static void vfe_update_awb_buf_addr( + boolean pingpong, uint32_t addr) +{ + if (pingpong == FALSE) + writel(addr, ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR); + else + writel(addr, ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR); +} + +static void vfe_send_awb_stats_msg(uint32_t awbBufAddress) +{ + /* unsigned long flags; */ + struct vfe_message *msg; + + msg = + kzalloc(sizeof(struct vfe_message), GFP_ATOMIC); + if (!msg) + return; + + /* fill message with right content. */ + /* @todo This is causing issues, need further investigate */ + /* spin_lock_irqsave(&ctrl->state_lock, flags); */ + if (ctrl->vstate != VFE_STATE_ACTIVE) { + kfree(msg); + goto awb_stats_done; + } + + msg->_d = VFE_MSG_ID_STATS_WB_EXP; + msg->_u.msgStatsWbExp.awbBuffer = awbBufAddress; + msg->_u.msgStatsWbExp.frameCounter = ctrl->vfeFrameId; + + vfe_proc_ops(VFE_MSG_ID_STATS_WB_EXP, + msg, sizeof(struct vfe_message)); + + ctrl->awbStatsControl.ackPending = TRUE; + +awb_stats_done: + /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */ + return; +} + +static void vfe_process_stats_awb_irq(void) +{ + boolean bufferAvailable; + + if (!(ctrl->awbStatsControl.ackPending)) { + + ctrl->awbStatsControl.pingPongStatus = + vfe_get_awb_pingpong_status(); + + bufferAvailable = (ctrl->awbStatsControl.pingPongStatus) ^ 1; + + ctrl->awbStatsControl.bufToRender = + vfe_read_awb_buf_addr(bufferAvailable); + + vfe_update_awb_buf_addr(bufferAvailable, + ctrl->awbStatsControl.nextFrameAddrBuf); + + vfe_send_awb_stats_msg(ctrl->awbStatsControl.bufToRender); + + } else + ctrl->awbStatsControl.droppedStatsFrameCount++; +} + +static void vfe_process_sync_timer_irq( + struct vfe_interrupt_status *irqstatus) +{ + if (irqstatus->syncTimer0Irq) + vfe_send_msg_no_payload(VFE_MSG_ID_SYNC_TIMER0_DONE); + + if (irqstatus->syncTimer1Irq) + vfe_send_msg_no_payload(VFE_MSG_ID_SYNC_TIMER1_DONE); + + if (irqstatus->syncTimer2Irq) + vfe_send_msg_no_payload(VFE_MSG_ID_SYNC_TIMER2_DONE); +} + +static void vfe_process_async_timer_irq( + struct vfe_interrupt_status *irqstatus) +{ + + if (irqstatus->asyncTimer0Irq) + vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER0_DONE); + + if (irqstatus->asyncTimer1Irq) + vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER1_DONE); + + if (irqstatus->asyncTimer2Irq) + vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER2_DONE); + + if (irqstatus->asyncTimer3Irq) + vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER3_DONE); +} + +static void vfe_send_violation_msg(void) +{ + vfe_send_msg_no_payload(VFE_MSG_ID_VIOLATION); +} + +static void vfe_send_async_timer_msg(void) +{ + vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER0_DONE); +} + +static void vfe_write_gamma_table(uint8_t channel, + boolean bank, int16_t *pTable) +{ + uint16_t i; + + enum VFE_DMI_RAM_SEL dmiRamSel = NO_MEM_SELECTED; + + switch (channel) { + case 0: + if (bank == 0) + dmiRamSel = RGBLUT_RAM_CH0_BANK0; + else + dmiRamSel = RGBLUT_RAM_CH0_BANK1; + break; + + case 1: + if (bank == 0) + dmiRamSel = RGBLUT_RAM_CH1_BANK0; + else + dmiRamSel = RGBLUT_RAM_CH1_BANK1; + break; + + case 2: + if (bank == 0) + dmiRamSel = RGBLUT_RAM_CH2_BANK0; + else + dmiRamSel = RGBLUT_RAM_CH2_BANK1; + break; + + default: + break; + } + + vfe_program_dmi_cfg(dmiRamSel); + + for (i = 0; i < VFE_GAMMA_TABLE_LENGTH; i++) { + writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO); + pTable++; + } + + /* After DMI transfer, need to set the DMI_CFG to unselect any SRAM + unselect the SRAM Bank. */ + writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG); +} + +static void vfe_prog_hw_testgen_cmd(uint32_t value) +{ + writel(value, ctrl->vfebase + VFE_HW_TESTGEN_CMD); +} + +static inline void vfe_read_irq_status(struct vfe_irq_thread_msg *out) +{ + uint32_t *temp; + + memset(out, 0, sizeof(struct vfe_irq_thread_msg)); + + temp = (uint32_t *)(ctrl->vfebase + VFE_IRQ_STATUS); + out->vfeIrqStatus = readl(temp); + + temp = (uint32_t *)(ctrl->vfebase + CAMIF_STATUS); + out->camifStatus = readl(temp); + writel(0x7, ctrl->vfebase + CAMIF_COMMAND); + writel(0x3, ctrl->vfebase + CAMIF_COMMAND); + CDBG("camifStatus = 0x%x\n", out->camifStatus); + +/* + temp = (uint32_t *)(ctrl->vfebase + VFE_DEMOSAIC_STATUS); + out->demosaicStatus = readl(temp); + + temp = (uint32_t *)(ctrl->vfebase + VFE_ASF_MAX_EDGE); + out->asfMaxEdge = readl(temp); + + temp = (uint32_t *)(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PM_STATS_0); +*/ + +#if 0 + out->pmInfo.encPathPmInfo.yWrPmStats0 = readl(temp++); + out->pmInfo.encPathPmInfo.yWrPmStats1 = readl(temp++); + out->pmInfo.encPathPmInfo.cbcrWrPmStats0 = readl(temp++); + out->pmInfo.encPathPmInfo.cbcrWrPmStats1 = readl(temp++); + out->pmInfo.viewPathPmInfo.yWrPmStats0 = readl(temp++); + out->pmInfo.viewPathPmInfo.yWrPmStats1 = readl(temp++); + out->pmInfo.viewPathPmInfo.cbcrWrPmStats0 = readl(temp++); + out->pmInfo.viewPathPmInfo.cbcrWrPmStats1 = readl(temp); +#endif /* if 0 Jeff */ +} + +static struct vfe_interrupt_status +vfe_parse_interrupt_status(uint32_t irqStatusIn) +{ + struct vfe_irqenable hwstat; + struct vfe_interrupt_status ret; + boolean temp; + + memset(&hwstat, 0, sizeof(hwstat)); + memset(&ret, 0, sizeof(ret)); + + hwstat = *((struct vfe_irqenable *)(&irqStatusIn)); + + ret.camifErrorIrq = hwstat.camifErrorIrq; + ret.camifSofIrq = hwstat.camifSofIrq; + ret.camifEolIrq = hwstat.camifEolIrq; + ret.camifEofIrq = hwstat.camifEofIrq; + ret.camifEpoch1Irq = hwstat.camifEpoch1Irq; + ret.camifEpoch2Irq = hwstat.camifEpoch2Irq; + ret.camifOverflowIrq = hwstat.camifOverflowIrq; + ret.ceIrq = hwstat.ceIrq; + ret.regUpdateIrq = hwstat.regUpdateIrq; + ret.resetAckIrq = hwstat.resetAckIrq; + ret.encYPingpongIrq = hwstat.encYPingpongIrq; + ret.encCbcrPingpongIrq = hwstat.encCbcrPingpongIrq; + ret.viewYPingpongIrq = hwstat.viewYPingpongIrq; + ret.viewCbcrPingpongIrq = hwstat.viewCbcrPingpongIrq; + ret.rdPingpongIrq = hwstat.rdPingpongIrq; + ret.afPingpongIrq = hwstat.afPingpongIrq; + ret.awbPingpongIrq = hwstat.awbPingpongIrq; + ret.histPingpongIrq = hwstat.histPingpongIrq; + ret.encIrq = hwstat.encIrq; + ret.viewIrq = hwstat.viewIrq; + ret.busOverflowIrq = hwstat.busOverflowIrq; + ret.afOverflowIrq = hwstat.afOverflowIrq; + ret.awbOverflowIrq = hwstat.awbOverflowIrq; + ret.syncTimer0Irq = hwstat.syncTimer0Irq; + ret.syncTimer1Irq = hwstat.syncTimer1Irq; + ret.syncTimer2Irq = hwstat.syncTimer2Irq; + ret.asyncTimer0Irq = hwstat.asyncTimer0Irq; + ret.asyncTimer1Irq = hwstat.asyncTimer1Irq; + ret.asyncTimer2Irq = hwstat.asyncTimer2Irq; + ret.asyncTimer3Irq = hwstat.asyncTimer3Irq; + ret.axiErrorIrq = hwstat.axiErrorIrq; + ret.violationIrq = hwstat.violationIrq; + + /* logic OR of any error bits + * although each irq corresponds to a bit, the data type here is a + * boolean already. hence use logic operation. + */ + temp = + ret.camifErrorIrq || + ret.camifOverflowIrq || + ret.afOverflowIrq || + ret.awbPingpongIrq || + ret.busOverflowIrq || + ret.axiErrorIrq || + ret.violationIrq; + + ret.anyErrorIrqs = temp; + + /* logic OR of any output path bits*/ + temp = + ret.encYPingpongIrq || + ret.encCbcrPingpongIrq || + ret.encIrq; + + ret.anyOutput2PathIrqs = temp; + + temp = + ret.viewYPingpongIrq || + ret.viewCbcrPingpongIrq || + ret.viewIrq; + + ret.anyOutput1PathIrqs = temp; + + ret.anyOutputPathIrqs = + ret.anyOutput1PathIrqs || + ret.anyOutput2PathIrqs; + + /* logic OR of any sync timer bits*/ + temp = + ret.syncTimer0Irq || + ret.syncTimer1Irq || + ret.syncTimer2Irq; + + ret.anySyncTimerIrqs = temp; + + /* logic OR of any async timer bits*/ + temp = + ret.asyncTimer0Irq || + ret.asyncTimer1Irq || + ret.asyncTimer2Irq || + ret.asyncTimer3Irq; + + ret.anyAsyncTimerIrqs = temp; + + /* bool for all interrupts that are not allowed in idle state */ + temp = + ret.anyErrorIrqs || + ret.anyOutputPathIrqs || + ret.anySyncTimerIrqs || + ret.regUpdateIrq || + ret.awbPingpongIrq || + ret.afPingpongIrq || + ret.camifSofIrq || + ret.camifEpoch2Irq || + ret.camifEpoch1Irq; + + ret.anyIrqForActiveStatesOnly = + temp; + + return ret; +} + +static struct vfe_frame_asf_info +vfe_get_asf_frame_info(struct vfe_irq_thread_msg *in) +{ + struct vfe_asf_info asfInfoTemp; + struct vfe_frame_asf_info rc; + + memset(&rc, 0, sizeof(rc)); + memset(&asfInfoTemp, 0, sizeof(asfInfoTemp)); + + asfInfoTemp = + *((struct vfe_asf_info *)(&(in->asfMaxEdge))); + + rc.asfHbiCount = asfInfoTemp.HBICount; + rc.asfMaxEdge = asfInfoTemp.maxEdge; + + return rc; +} + +static struct vfe_frame_bpc_info +vfe_get_demosaic_frame_info(struct vfe_irq_thread_msg *in) +{ + struct vfe_bps_info bpcInfoTemp; + struct vfe_frame_bpc_info rc; + + memset(&rc, 0, sizeof(rc)); + memset(&bpcInfoTemp, 0, sizeof(bpcInfoTemp)); + + bpcInfoTemp = + *((struct vfe_bps_info *)(&(in->demosaicStatus))); + + rc.greenDefectPixelCount = + bpcInfoTemp.greenBadPixelCount; + + rc.redBlueDefectPixelCount = + bpcInfoTemp.RedBlueBadPixelCount; + + return rc; +} + +static struct vfe_msg_camif_status +vfe_get_camif_status(struct vfe_irq_thread_msg *in) +{ + struct vfe_camif_stats camifStatusTemp; + struct vfe_msg_camif_status rc; + + memset(&rc, 0, sizeof(rc)); + memset(&camifStatusTemp, 0, sizeof(camifStatusTemp)); + + camifStatusTemp = + *((struct vfe_camif_stats *)(&(in->camifStatus))); + + rc.camifState = (boolean)camifStatusTemp.camifHalt; + rc.lineCount = camifStatusTemp.lineCount; + rc.pixelCount = camifStatusTemp.pixelCount; + + return rc; +} + +static struct vfe_bus_performance_monitor +vfe_get_performance_monitor_data(struct vfe_irq_thread_msg *in) +{ + struct vfe_bus_performance_monitor rc; + memset(&rc, 0, sizeof(rc)); + + rc.encPathPmInfo.yWrPmStats0 = + in->pmInfo.encPathPmInfo.yWrPmStats0; + rc.encPathPmInfo.yWrPmStats1 = + in->pmInfo.encPathPmInfo.yWrPmStats1; + rc.encPathPmInfo.cbcrWrPmStats0 = + in->pmInfo.encPathPmInfo.cbcrWrPmStats0; + rc.encPathPmInfo.cbcrWrPmStats1 = + in->pmInfo.encPathPmInfo.cbcrWrPmStats1; + rc.viewPathPmInfo.yWrPmStats0 = + in->pmInfo.viewPathPmInfo.yWrPmStats0; + rc.viewPathPmInfo.yWrPmStats1 = + in->pmInfo.viewPathPmInfo.yWrPmStats1; + rc.viewPathPmInfo.cbcrWrPmStats0 = + in->pmInfo.viewPathPmInfo.cbcrWrPmStats0; + rc.viewPathPmInfo.cbcrWrPmStats1 = + in->pmInfo.viewPathPmInfo.cbcrWrPmStats1; + + return rc; +} + +static void vfe_process_reg_update_irq(void) +{ + CDBG("vfe_process_reg_update_irq: ackPendingFlag is %d\n", + ctrl->vfeStartAckPendingFlag); + if (ctrl->vfeStartAckPendingFlag == TRUE) { + vfe_send_msg_no_payload(VFE_MSG_ID_START_ACK); + ctrl->vfeStartAckPendingFlag = FALSE; + } else + vfe_send_msg_no_payload(VFE_MSG_ID_UPDATE_ACK); +} + +static void vfe_process_reset_irq(void) +{ + /* unsigned long flags; */ + + /* @todo This is causing issues, need further investigate */ + /* spin_lock_irqsave(&ctrl->state_lock, flags); */ + ctrl->vstate = VFE_STATE_IDLE; + /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */ + + if (ctrl->vfeStopAckPending == TRUE) { + ctrl->vfeStopAckPending = FALSE; + vfe_send_msg_no_payload(VFE_MSG_ID_STOP_ACK); + } else { + vfe_set_default_reg_values(); + vfe_send_msg_no_payload(VFE_MSG_ID_RESET_ACK); + } +} + +static void vfe_process_pingpong_irq(struct vfe_output_path *in, + uint8_t fragmentCount) +{ + uint16_t circularIndex; + uint32_t nextFragmentAddr; + + /* get next fragment address from circular buffer */ + circularIndex = (in->fragIndex) % (2 * fragmentCount); + nextFragmentAddr = in->addressBuffer[circularIndex]; + + in->fragIndex = circularIndex + 1; + + /* use next fragment to program hardware ping/pong address. */ + if (in->hwCurrentFlag == ping) { + writel(nextFragmentAddr, in->hwRegPingAddress); + in->hwCurrentFlag = pong; + + } else { + writel(nextFragmentAddr, in->hwRegPongAddress); + in->hwCurrentFlag = ping; + } +} + +static void vfe_send_output2_msg( + struct vfe_msg_output *pPayload) +{ + /* unsigned long flags; */ + struct vfe_message *msg; + + msg = kzalloc(sizeof(struct vfe_message), GFP_ATOMIC); + if (!msg) + return; + + /* fill message with right content. */ + /* @todo This is causing issues, need further investigate */ + /* spin_lock_irqsave(&ctrl->state_lock, flags); */ + if (ctrl->vstate != VFE_STATE_ACTIVE) { + kfree(msg); + goto output2_msg_done; + } + + msg->_d = VFE_MSG_ID_OUTPUT2; + + memcpy(&(msg->_u.msgOutput2), + (void *)pPayload, sizeof(struct vfe_msg_output)); + + vfe_proc_ops(VFE_MSG_ID_OUTPUT2, + msg, sizeof(struct vfe_message)); + + ctrl->encPath.ackPending = TRUE; + + if (!(ctrl->vfeRequestedSnapShotCount <= 3) && + (ctrl->vfeOperationMode == + VFE_START_OPERATION_MODE_SNAPSHOT)) + ctrl->encPath.ackPending = TRUE; + +output2_msg_done: + /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */ + return; +} + +static void vfe_send_output1_msg( + struct vfe_msg_output *pPayload) +{ + /* unsigned long flags; */ + struct vfe_message *msg; + + msg = kzalloc(sizeof(struct vfe_message), GFP_ATOMIC); + if (!msg) + return; + + /* @todo This is causing issues, need further investigate */ + /* spin_lock_irqsave(&ctrl->state_lock, flags); */ + if (ctrl->vstate != VFE_STATE_ACTIVE) { + kfree(msg); + goto output1_msg_done; + } + + msg->_d = VFE_MSG_ID_OUTPUT1; + memmove(&(msg->_u), + (void *)pPayload, sizeof(struct vfe_msg_output)); + + vfe_proc_ops(VFE_MSG_ID_OUTPUT1, + msg, sizeof(struct vfe_message)); + + ctrl->viewPath.ackPending = TRUE; + + if (!(ctrl->vfeRequestedSnapShotCount <= 3) && + (ctrl->vfeOperationMode == + VFE_START_OPERATION_MODE_SNAPSHOT)) + ctrl->viewPath.ackPending = TRUE; + +output1_msg_done: + /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */ + return; +} + +static void vfe_send_output_msg(boolean whichOutputPath, + uint32_t yPathAddr, uint32_t cbcrPathAddr) +{ + struct vfe_msg_output msgPayload; + + msgPayload.yBuffer = yPathAddr; + msgPayload.cbcrBuffer = cbcrPathAddr; + + /* asf info is common for both output1 and output2 */ +#if 0 + msgPayload.asfInfo.asfHbiCount = ctrl->vfeAsfFrameInfo.asfHbiCount; + msgPayload.asfInfo.asfMaxEdge = ctrl->vfeAsfFrameInfo.asfMaxEdge; + + /* demosaic info is common for both output1 and output2 */ + msgPayload.bpcInfo.greenDefectPixelCount = + ctrl->vfeBpcFrameInfo.greenDefectPixelCount; + msgPayload.bpcInfo.redBlueDefectPixelCount = + ctrl->vfeBpcFrameInfo.redBlueDefectPixelCount; +#endif /* if 0 */ + + /* frame ID is common for both paths. */ + msgPayload.frameCounter = ctrl->vfeFrameId; + + if (whichOutputPath) { + /* msgPayload.pmData = ctrl->vfePmData.encPathPmInfo; */ + vfe_send_output2_msg(&msgPayload); + } else { + /* msgPayload.pmData = ctrl->vfePmData.viewPathPmInfo; */ + vfe_send_output1_msg(&msgPayload); + } +} + +static void vfe_process_frame_done_irq_multi_frag( + struct vfe_output_path_combo *in) +{ + uint32_t yAddress, cbcrAddress; + uint16_t idx; + uint32_t *ptrY; + uint32_t *ptrCbcr; + const uint32_t *ptrSrc; + uint8_t i; + + if (!in->ackPending) { + + idx = (in->currentFrame) * (in->fragCount); + + /* Send output message. */ + yAddress = in->yPath.addressBuffer[idx]; + cbcrAddress = in->cbcrPath.addressBuffer[idx]; + + /* copy next frame to current frame. */ + ptrSrc = in->nextFrameAddrBuf; + ptrY = (uint32_t *)&(in->yPath.addressBuffer[idx]); + ptrCbcr = (uint32_t *)&(in->cbcrPath.addressBuffer[idx]); + + /* Copy Y address */ + for (i = 0; i < in->fragCount; i++) + *ptrY++ = *ptrSrc++; + + /* Copy Cbcr address */ + for (i = 0; i < in->fragCount; i++) + *ptrCbcr++ = *ptrSrc++; + + vfe_send_output_msg(in->whichOutputPath, yAddress, cbcrAddress); + + } else { + if (in->whichOutputPath == 0) + ctrl->vfeDroppedFrameCounts.output1Count++; + + if (in->whichOutputPath == 1) + ctrl->vfeDroppedFrameCounts.output2Count++; + } + + /* toggle current frame. */ + in->currentFrame = in->currentFrame^1; + + if (ctrl->vfeOperationMode) + in->snapshotPendingCount--; +} + +static void vfe_process_frame_done_irq_no_frag_io( + struct vfe_output_path_combo *in, uint32_t *pNextAddr, + uint32_t *pdestRenderAddr) +{ + uint32_t busPingPongStatus; + uint32_t tempAddress; + + /* 1. read hw status register. */ + busPingPongStatus = + readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS); + + CDBG("hardware status is 0x%x\n", busPingPongStatus); + + /* 2. determine ping or pong */ + /* use cbcr status */ + busPingPongStatus = busPingPongStatus & (1<<(in->cbcrStatusBit)); + + /* 3. read out address and update address */ + if (busPingPongStatus == 0) { + /* hw is working on ping, render pong buffer */ + /* a. read out pong address */ + /* read out y address. */ + tempAddress = readl(in->yPath.hwRegPongAddress); + + CDBG("pong 1 addr = 0x%x\n", tempAddress); + *pdestRenderAddr++ = tempAddress; + /* read out cbcr address. */ + tempAddress = readl(in->cbcrPath.hwRegPongAddress); + + CDBG("pong 2 addr = 0x%x\n", tempAddress); + *pdestRenderAddr = tempAddress; + + /* b. update pong address */ + writel(*pNextAddr++, in->yPath.hwRegPongAddress); + writel(*pNextAddr, in->cbcrPath.hwRegPongAddress); + } else { + /* hw is working on pong, render ping buffer */ + + /* a. read out ping address */ + tempAddress = readl(in->yPath.hwRegPingAddress); + CDBG("ping 1 addr = 0x%x\n", tempAddress); + *pdestRenderAddr++ = tempAddress; + tempAddress = readl(in->cbcrPath.hwRegPingAddress); + + CDBG("ping 2 addr = 0x%x\n", tempAddress); + *pdestRenderAddr = tempAddress; + + /* b. update ping address */ + writel(*pNextAddr++, in->yPath.hwRegPingAddress); + CDBG("NextAddress = 0x%x\n", *pNextAddr); + writel(*pNextAddr, in->cbcrPath.hwRegPingAddress); + } +} + +static void vfe_process_frame_done_irq_no_frag( + struct vfe_output_path_combo *in) +{ + uint32_t addressToRender[2]; + static uint32_t fcnt; + + if (fcnt++ < 3) + return; + + if (!in->ackPending) { + vfe_process_frame_done_irq_no_frag_io(in, + in->nextFrameAddrBuf, addressToRender); + + /* use addressToRender to send out message. */ + vfe_send_output_msg(in->whichOutputPath, + addressToRender[0], addressToRender[1]); + + } else { + /* ackPending is still there, accumulate dropped frame count. + * These count can be read through ioctrl command. */ + CDBG("waiting frame ACK\n"); + + if (in->whichOutputPath == 0) + ctrl->vfeDroppedFrameCounts.output1Count++; + + if (in->whichOutputPath == 1) + ctrl->vfeDroppedFrameCounts.output2Count++; + } + + /* in case of multishot when upper layer did not ack, there will still + * be a snapshot done msg sent out, even though the number of frames + * sent out may be less than the desired number of frames. snapshot + * done msg would be helpful to indicate that vfe pipeline has stop, + * and in good known state. + */ + if (ctrl->vfeOperationMode) + in->snapshotPendingCount--; +} + +static void vfe_process_output_path_irq( + struct vfe_interrupt_status *irqstatus) +{ + /* unsigned long flags; */ + + /* process the view path interrupts */ + if (irqstatus->anyOutput1PathIrqs) { + if (ctrl->viewPath.multiFrag) { + + if (irqstatus->viewCbcrPingpongIrq) + vfe_process_pingpong_irq( + &(ctrl->viewPath.cbcrPath), + ctrl->viewPath.fragCount); + + if (irqstatus->viewYPingpongIrq) + vfe_process_pingpong_irq( + &(ctrl->viewPath.yPath), + ctrl->viewPath.fragCount); + + if (irqstatus->viewIrq) + vfe_process_frame_done_irq_multi_frag( + &ctrl->viewPath); + + } else { + /* typical case for no fragment, + only frame done irq is enabled. */ + if (irqstatus->viewIrq) + vfe_process_frame_done_irq_no_frag( + &ctrl->viewPath); + } + } + + /* process the encoder path interrupts */ + if (irqstatus->anyOutput2PathIrqs) { + if (ctrl->encPath.multiFrag) { + if (irqstatus->encCbcrPingpongIrq) + vfe_process_pingpong_irq( + &(ctrl->encPath.cbcrPath), + ctrl->encPath.fragCount); + + if (irqstatus->encYPingpongIrq) + vfe_process_pingpong_irq(&(ctrl->encPath.yPath), + ctrl->encPath.fragCount); + + if (irqstatus->encIrq) + vfe_process_frame_done_irq_multi_frag( + &ctrl->encPath); + + } else { + if (irqstatus->encIrq) + vfe_process_frame_done_irq_no_frag( + &ctrl->encPath); + } + } + + if (ctrl->vfeOperationMode) { + if ((ctrl->encPath.snapshotPendingCount == 0) && + (ctrl->viewPath.snapshotPendingCount == 0)) { + + /* @todo This is causing issues, further investigate */ + /* spin_lock_irqsave(&ctrl->state_lock, flags); */ + ctrl->vstate = VFE_STATE_IDLE; + /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */ + + vfe_send_msg_no_payload(VFE_MSG_ID_SNAPSHOT_DONE); + vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_STOP); + vfe_pm_stop(); + } + } +} + +static void vfe_do_tasklet(unsigned long data) +{ + unsigned long flags; + + struct isr_queue_cmd *qcmd = NULL; + + CDBG("=== vfe_do_tasklet start === \n"); + + spin_lock_irqsave(&ctrl->tasklet_lock, flags); + qcmd = list_first_entry(&ctrl->tasklet_q, + struct isr_queue_cmd, list); + + if (!qcmd) { + spin_unlock_irqrestore(&ctrl->tasklet_lock, flags); + return; + } + + list_del(&qcmd->list); + spin_unlock_irqrestore(&ctrl->tasklet_lock, flags); + + if (qcmd->vfeInterruptStatus.regUpdateIrq) { + CDBG("irq regUpdateIrq\n"); + vfe_process_reg_update_irq(); + } + + if (qcmd->vfeInterruptStatus.resetAckIrq) { + CDBG("irq resetAckIrq\n"); + vfe_process_reset_irq(); + } + + spin_lock_irqsave(&ctrl->state_lock, flags); + if (ctrl->vstate != VFE_STATE_ACTIVE) { + spin_unlock_irqrestore(&ctrl->state_lock, flags); + return; + } + spin_unlock_irqrestore(&ctrl->state_lock, flags); + +#if 0 + if (qcmd->vfeInterruptStatus.camifEpoch1Irq) + vfe_send_msg_no_payload(VFE_MSG_ID_EPOCH1); + + if (qcmd->vfeInterruptStatus.camifEpoch2Irq) + vfe_send_msg_no_payload(VFE_MSG_ID_EPOCH2); +#endif /* Jeff */ + + /* next, check output path related interrupts. */ + if (qcmd->vfeInterruptStatus.anyOutputPathIrqs) { + CDBG("irq anyOutputPathIrqs\n"); + vfe_process_output_path_irq(&qcmd->vfeInterruptStatus); + } + + if (qcmd->vfeInterruptStatus.afPingpongIrq) + vfe_process_stats_af_irq(); + + if (qcmd->vfeInterruptStatus.awbPingpongIrq) + vfe_process_stats_awb_irq(); + + /* any error irqs*/ + if (qcmd->vfeInterruptStatus.anyErrorIrqs) + vfe_process_error_irq(&qcmd->vfeInterruptStatus); + +#if 0 + if (qcmd->vfeInterruptStatus.anySyncTimerIrqs) + vfe_process_sync_timer_irq(); + + if (qcmd->vfeInterruptStatus.anyAsyncTimerIrqs) + vfe_process_async_timer_irq(); +#endif /* Jeff */ + + if (qcmd->vfeInterruptStatus.camifSofIrq) { + CDBG("irq camifSofIrq\n"); + vfe_process_camif_sof_irq(); + } + + kfree(qcmd); + CDBG("=== vfe_do_tasklet end === \n"); +} + +DECLARE_TASKLET(vfe_tasklet, vfe_do_tasklet, 0); + +static irqreturn_t vfe_parse_irq(int irq_num, void *data) +{ + unsigned long flags; + uint32_t irqStatusLocal; + struct vfe_irq_thread_msg irq; + struct isr_queue_cmd *qcmd; + + CDBG("vfe_parse_irq\n"); + + vfe_read_irq_status(&irq); + + if (irq.vfeIrqStatus == 0) { + CDBG("vfe_parse_irq: irq.vfeIrqStatus is 0\n"); + return IRQ_HANDLED; + } + + qcmd = kzalloc(sizeof(struct isr_queue_cmd), + GFP_ATOMIC); + if (!qcmd) { + CDBG("vfe_parse_irq: qcmd malloc failed!\n"); + return IRQ_HANDLED; + } + + spin_lock_irqsave(&ctrl->ack_lock, flags); + + if (ctrl->vfeStopAckPending) + irqStatusLocal = + (VFE_IMASK_WHILE_STOPPING & irq.vfeIrqStatus); + else + irqStatusLocal = + ((ctrl->vfeImaskPacked | VFE_IMASK_ERROR_ONLY) & + irq.vfeIrqStatus); + + spin_unlock_irqrestore(&ctrl->ack_lock, flags); + + /* first parse the interrupt status to local data structures. */ + qcmd->vfeInterruptStatus = vfe_parse_interrupt_status(irqStatusLocal); + qcmd->vfeAsfFrameInfo = vfe_get_asf_frame_info(&irq); + qcmd->vfeBpcFrameInfo = vfe_get_demosaic_frame_info(&irq); + qcmd->vfeCamifStatusLocal = vfe_get_camif_status(&irq); + qcmd->vfePmData = vfe_get_performance_monitor_data(&irq); + + spin_lock_irqsave(&ctrl->tasklet_lock, flags); + list_add_tail(&qcmd->list, &ctrl->tasklet_q); + spin_unlock_irqrestore(&ctrl->tasklet_lock, flags); + tasklet_schedule(&vfe_tasklet); + + /* clear the pending interrupt of the same kind.*/ + writel(irq.vfeIrqStatus, ctrl->vfebase + VFE_IRQ_CLEAR); + + return IRQ_HANDLED; +} + +int vfe_cmd_init(struct msm_vfe_callback *presp, + struct platform_device *pdev, void *sdata) +{ + struct resource *vfemem, *vfeirq, *vfeio; + int rc; + + vfemem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!vfemem) { + CDBG("no mem resource?\n"); + return -ENODEV; + } + + vfeirq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!vfeirq) { + CDBG("no irq resource?\n"); + return -ENODEV; + } + + vfeio = request_mem_region(vfemem->start, + resource_size(vfemem), pdev->name); + if (!vfeio) { + CDBG("VFE region already claimed\n"); + return -EBUSY; + } + + ctrl = + kzalloc(sizeof(struct msm_vfe8x_ctrl), GFP_KERNEL); + if (!ctrl) { + rc = -ENOMEM; + goto cmd_init_failed1; + } + + ctrl->vfeirq = vfeirq->start; + + ctrl->vfebase = + ioremap(vfemem->start, (vfemem->end - vfemem->start) + 1); + if (!ctrl->vfebase) { + rc = -ENOMEM; + goto cmd_init_failed2; + } + + rc = request_irq(ctrl->vfeirq, vfe_parse_irq, + IRQF_TRIGGER_RISING, "vfe", 0); + if (rc < 0) + goto cmd_init_failed2; + + if (presp && presp->vfe_resp) + ctrl->resp = presp; + else { + rc = -EINVAL; + goto cmd_init_failed3; + } + + ctrl->extdata = + kmalloc(sizeof(struct vfe_frame_extra), GFP_KERNEL); + if (!ctrl->extdata) { + rc = -ENOMEM; + goto cmd_init_failed3; + } + + spin_lock_init(&ctrl->ack_lock); + spin_lock_init(&ctrl->state_lock); + spin_lock_init(&ctrl->io_lock); + + ctrl->extlen = sizeof(struct vfe_frame_extra); + + spin_lock_init(&ctrl->tasklet_lock); + INIT_LIST_HEAD(&ctrl->tasklet_q); + + ctrl->syncdata = sdata; + return 0; + +cmd_init_failed3: + disable_irq(ctrl->vfeirq); + free_irq(ctrl->vfeirq, 0); + iounmap(ctrl->vfebase); +cmd_init_failed2: + kfree(ctrl); +cmd_init_failed1: + release_mem_region(vfemem->start, (vfemem->end - vfemem->start) + 1); + return rc; +} + +void vfe_cmd_release(struct platform_device *dev) +{ + struct resource *mem; + + disable_irq(ctrl->vfeirq); + free_irq(ctrl->vfeirq, 0); + + iounmap(ctrl->vfebase); + mem = platform_get_resource(dev, IORESOURCE_MEM, 0); + release_mem_region(mem->start, (mem->end - mem->start) + 1); + + ctrl->extlen = 0; + + kfree(ctrl->extdata); + kfree(ctrl); +} + +void vfe_stats_af_stop(void) +{ + ctrl->vfeStatsCmdLocal.autoFocusEnable = FALSE; + ctrl->vfeImaskLocal.afPingpongIrq = FALSE; +} + +void vfe_stop(void) +{ + boolean vfeAxiBusy; + uint32_t vfeAxiStauts; + + /* for reset hw modules, and send msg when reset_irq comes.*/ + ctrl->vfeStopAckPending = TRUE; + + ctrl->vfeStatsPingPongReloadFlag = FALSE; + vfe_pm_stop(); + + /* disable all interrupts. */ + vfe_program_irq_mask(VFE_DISABLE_ALL_IRQS); + + /* in either continuous or snapshot mode, stop command can be issued + * at any time. + */ + vfe_camif_stop_immediately(); + vfe_program_axi_cmd(AXI_HALT); + vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_STOP); + + vfeAxiBusy = TRUE; + + while (vfeAxiBusy) { + vfeAxiStauts = vfe_read_axi_status(); + if ((vfeAxiStauts & AXI_STATUS_BUSY_MASK) != 0) + vfeAxiBusy = FALSE; + } + + vfe_program_axi_cmd(AXI_HALT_CLEAR); + + /* clear all pending interrupts */ + writel(VFE_CLEAR_ALL_IRQS, ctrl->vfebase + VFE_IRQ_CLEAR); + + /* enable reset_ack and async timer interrupt only while stopping + * the pipeline. + */ + vfe_program_irq_mask(VFE_IMASK_WHILE_STOPPING); + + vfe_program_global_reset_cmd(VFE_RESET_UPON_STOP_CMD); +} + +void vfe_update(void) +{ + ctrl->vfeModuleEnableLocal.statsEnable = + ctrl->vfeStatsCmdLocal.autoFocusEnable | + ctrl->vfeStatsCmdLocal.axwEnable; + + vfe_reg_module_cfg(&ctrl->vfeModuleEnableLocal); + + vfe_program_stats_cmd(&ctrl->vfeStatsCmdLocal); + + ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal); + vfe_program_irq_mask(ctrl->vfeImaskPacked); + + if ((ctrl->vfeModuleEnableLocal.statsEnable == TRUE) && + (ctrl->vfeStatsPingPongReloadFlag == FALSE)) { + ctrl->vfeStatsPingPongReloadFlag = TRUE; + + ctrl->vfeBusCmdLocal.statsPingpongReload = TRUE; + vfe_reg_bus_cmd(&ctrl->vfeBusCmdLocal); + } + + vfe_program_reg_update_cmd(VFE_REG_UPDATE_TRIGGER); +} + +int vfe_rgb_gamma_update(struct vfe_cmd_rgb_gamma_config *in) +{ + int rc = 0; + + ctrl->vfeModuleEnableLocal.rgbLUTEnable = in->enable; + + switch (in->channelSelect) { + case RGB_GAMMA_CH0_SELECTED: + ctrl->vfeGammaLutSel.ch0BankSelect ^= 1; + vfe_write_gamma_table(0, + ctrl->vfeGammaLutSel.ch0BankSelect, in->table); + break; + + case RGB_GAMMA_CH1_SELECTED: + ctrl->vfeGammaLutSel.ch1BankSelect ^= 1; + vfe_write_gamma_table(1, + ctrl->vfeGammaLutSel.ch1BankSelect, in->table); + break; + + case RGB_GAMMA_CH2_SELECTED: + ctrl->vfeGammaLutSel.ch2BankSelect ^= 1; + vfe_write_gamma_table(2, + ctrl->vfeGammaLutSel.ch2BankSelect, in->table); + break; + + case RGB_GAMMA_CH0_CH1_SELECTED: + ctrl->vfeGammaLutSel.ch0BankSelect ^= 1; + ctrl->vfeGammaLutSel.ch1BankSelect ^= 1; + vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect, + in->table); + vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect, + in->table); + break; + + case RGB_GAMMA_CH0_CH2_SELECTED: + ctrl->vfeGammaLutSel.ch0BankSelect ^= 1; + ctrl->vfeGammaLutSel.ch2BankSelect ^= 1; + vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect, + in->table); + vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect, + in->table); + break; + + case RGB_GAMMA_CH1_CH2_SELECTED: + ctrl->vfeGammaLutSel.ch1BankSelect ^= 1; + ctrl->vfeGammaLutSel.ch2BankSelect ^= 1; + vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect, + in->table); + vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect, + in->table); + break; + + case RGB_GAMMA_CH0_CH1_CH2_SELECTED: + ctrl->vfeGammaLutSel.ch0BankSelect ^= 1; + ctrl->vfeGammaLutSel.ch1BankSelect ^= 1; + ctrl->vfeGammaLutSel.ch2BankSelect ^= 1; + vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect, + in->table); + vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect, + in->table); + vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect, + in->table); + break; + + default: + return -EINVAL; + } /* switch */ + + /* update the gammaLutSel register. */ + vfe_program_lut_bank_sel(&ctrl->vfeGammaLutSel); + + return rc; +} + +int vfe_rgb_gamma_config(struct vfe_cmd_rgb_gamma_config *in) +{ + int rc = 0; + + ctrl->vfeModuleEnableLocal.rgbLUTEnable = in->enable; + + switch (in->channelSelect) { + case RGB_GAMMA_CH0_SELECTED: +vfe_write_gamma_table(0, 0, in->table); +break; + + case RGB_GAMMA_CH1_SELECTED: + vfe_write_gamma_table(1, 0, in->table); + break; + + case RGB_GAMMA_CH2_SELECTED: + vfe_write_gamma_table(2, 0, in->table); + break; + + case RGB_GAMMA_CH0_CH1_SELECTED: + vfe_write_gamma_table(0, 0, in->table); + vfe_write_gamma_table(1, 0, in->table); + break; + + case RGB_GAMMA_CH0_CH2_SELECTED: + vfe_write_gamma_table(0, 0, in->table); + vfe_write_gamma_table(2, 0, in->table); + break; + + case RGB_GAMMA_CH1_CH2_SELECTED: + vfe_write_gamma_table(1, 0, in->table); + vfe_write_gamma_table(2, 0, in->table); + break; + + case RGB_GAMMA_CH0_CH1_CH2_SELECTED: + vfe_write_gamma_table(0, 0, in->table); + vfe_write_gamma_table(1, 0, in->table); + vfe_write_gamma_table(2, 0, in->table); + break; + + default: + rc = -EINVAL; + break; + } /* switch */ + + return rc; +} + +void vfe_stats_af_ack(struct vfe_cmd_stats_af_ack *in) +{ + ctrl->afStatsControl.nextFrameAddrBuf = in->nextAFOutputBufferAddr; + ctrl->afStatsControl.ackPending = FALSE; +} + +void vfe_stats_wb_exp_ack(struct vfe_cmd_stats_wb_exp_ack *in) +{ + ctrl->awbStatsControl.nextFrameAddrBuf = in->nextWbExpOutputBufferAddr; + ctrl->awbStatsControl.ackPending = FALSE; +} + +void vfe_output2_ack(struct vfe_cmd_output_ack *in) +{ + const uint32_t *psrc; + uint32_t *pdest; + uint8_t i; + + pdest = ctrl->encPath.nextFrameAddrBuf; + + CDBG("output2_ack: ack addr = 0x%x\n", in->ybufaddr[0]); + + psrc = in->ybufaddr; + for (i = 0; i < ctrl->encPath.fragCount; i++) + *pdest++ = *psrc++; + + psrc = in->chromabufaddr; + for (i = 0; i < ctrl->encPath.fragCount; i++) + *pdest++ = *psrc++; + + ctrl->encPath.ackPending = FALSE; +} + +void vfe_output1_ack(struct vfe_cmd_output_ack *in) +{ + const uint32_t *psrc; + uint32_t *pdest; + uint8_t i; + + pdest = ctrl->viewPath.nextFrameAddrBuf; + + psrc = in->ybufaddr; + for (i = 0; i < ctrl->viewPath.fragCount; i++) + *pdest++ = *psrc++; + + psrc = in->chromabufaddr; + for (i = 0; i < ctrl->viewPath.fragCount; i++) + *pdest++ = *psrc++; + + ctrl->viewPath.ackPending = FALSE; +} + +void vfe_start(struct vfe_cmd_start *in) +{ + unsigned long flags; + uint32_t pmstatus = 0; + boolean rawmode; + uint32_t demperiod = 0; + uint32_t demeven = 0; + uint32_t demodd = 0; + + /* derived from other commands. (camif config, axi output config, + * etc) + */ + struct vfe_cfg hwcfg; + struct vfe_upsample_cfg chromupcfg; + + CDBG("vfe_start operationMode = %d\n", in->operationMode); + + memset(&hwcfg, 0, sizeof(hwcfg)); + memset(&chromupcfg, 0, sizeof(chromupcfg)); + + switch (in->pixel) { + case VFE_BAYER_RGRGRG: + demperiod = 1; + demeven = 0xC9; + demodd = 0xAC; + break; + + case VFE_BAYER_GRGRGR: + demperiod = 1; + demeven = 0x9C; + demodd = 0xCA; + break; + + case VFE_BAYER_BGBGBG: + demperiod = 1; + demeven = 0xCA; + demodd = 0x9C; + break; + + case VFE_BAYER_GBGBGB: + demperiod = 1; + demeven = 0xAC; + demodd = 0xC9; + break; + + case VFE_YUV_YCbYCr: + demperiod = 3; + demeven = 0x9CAC; + demodd = 0x9CAC; + break; + + case VFE_YUV_YCrYCb: + demperiod = 3; + demeven = 0xAC9C; + demodd = 0xAC9C; + break; + + case VFE_YUV_CbYCrY: + demperiod = 3; + demeven = 0xC9CA; + demodd = 0xC9CA; + break; + + case VFE_YUV_CrYCbY: + demperiod = 3; + demeven = 0xCAC9; + demodd = 0xCAC9; + break; + + default: + return; + } + + vfe_config_demux(demperiod, demeven, demodd); + + vfe_program_lut_bank_sel(&ctrl->vfeGammaLutSel); + + /* save variables to local. */ + ctrl->vfeOperationMode = in->operationMode; + if (ctrl->vfeOperationMode == + VFE_START_OPERATION_MODE_SNAPSHOT) { + /* in snapshot mode, initialize snapshot count*/ + ctrl->vfeSnapShotCount = in->snapshotCount; + + /* save the requested count, this is temporarily done, to + help with HJR / multishot. */ + ctrl->vfeRequestedSnapShotCount = ctrl->vfeSnapShotCount; + + CDBG("requested snapshot count = %d\n", ctrl->vfeSnapShotCount); + + /* Assumption is to have the same pattern and period for both + paths, if both paths are used. */ + if (ctrl->viewPath.pathEnabled) { + ctrl->viewPath.snapshotPendingCount = + in->snapshotCount; + + ctrl->vfeFrameSkipPattern = + ctrl->vfeFrameSkip.output1Pattern; + ctrl->vfeFrameSkipPeriod = + ctrl->vfeFrameSkip.output1Period; + } + + if (ctrl->encPath.pathEnabled) { + ctrl->encPath.snapshotPendingCount = + in->snapshotCount; + + ctrl->vfeFrameSkipPattern = + ctrl->vfeFrameSkip.output2Pattern; + ctrl->vfeFrameSkipPeriod = + ctrl->vfeFrameSkip.output2Period; + } + } + + /* enable color conversion for bayer sensor + if stats enabled, need to do color conversion. */ + if (in->pixel <= VFE_BAYER_GBGBGB) + ctrl->vfeStatsCmdLocal.colorConversionEnable = TRUE; + + vfe_program_stats_cmd(&ctrl->vfeStatsCmdLocal); + + if (in->pixel >= VFE_YUV_YCbYCr) + ctrl->vfeModuleEnableLocal.chromaUpsampleEnable = TRUE; + + ctrl->vfeModuleEnableLocal.demuxEnable = TRUE; + + /* if any stats module is enabled, the main bit is enabled. */ + ctrl->vfeModuleEnableLocal.statsEnable = + ctrl->vfeStatsCmdLocal.autoFocusEnable | + ctrl->vfeStatsCmdLocal.axwEnable; + + vfe_reg_module_cfg(&ctrl->vfeModuleEnableLocal); + + /* in case of offline processing, do not need to config camif. Having + * bus output enabled in camif_config register might confuse the + * hardware? + */ + if (in->inputSource != VFE_START_INPUT_SOURCE_AXI) { + vfe_reg_camif_config(&ctrl->vfeCamifConfigLocal); + } else { + /* offline processing, enable axi read */ + ctrl->vfeBusConfigLocal.stripeRdPathEn = TRUE; + ctrl->vfeBusCmdLocal.stripeReload = TRUE; + ctrl->vfeBusConfigLocal.rawPixelDataSize = + ctrl->axiInputDataSize; + } + + vfe_reg_bus_cfg(&ctrl->vfeBusConfigLocal); + + /* directly from start command */ + hwcfg.pixelPattern = in->pixel; + hwcfg.inputSource = in->inputSource; + writel(*(uint32_t *)&hwcfg, ctrl->vfebase + VFE_CFG); + + /* regardless module enabled or not, it does not hurt + * to program the cositing mode. */ + chromupcfg.chromaCositingForYCbCrInputs = + in->yuvInputCositingMode; + + writel(*(uint32_t *)&(chromupcfg), + ctrl->vfebase + VFE_CHROMA_UPSAMPLE_CFG); + + /* MISR to monitor the axi read. */ + writel(0xd8, ctrl->vfebase + VFE_BUS_MISR_MAST_CFG_0); + + /* clear all pending interrupts. */ + writel(VFE_CLEAR_ALL_IRQS, ctrl->vfebase + VFE_IRQ_CLEAR); + + /* define how composite interrupt work. */ + ctrl->vfeImaskCompositePacked = + vfe_irq_composite_pack(ctrl->vfeIrqCompositeMaskLocal); + + vfe_program_irq_composite_mask(ctrl->vfeImaskCompositePacked); + + /* enable all necessary interrupts. */ + ctrl->vfeImaskLocal.camifSofIrq = TRUE; + ctrl->vfeImaskLocal.regUpdateIrq = TRUE; + ctrl->vfeImaskLocal.resetAckIrq = TRUE; + + ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal); + vfe_program_irq_mask(ctrl->vfeImaskPacked); + + /* enable bus performance monitor */ + vfe_8k_pm_start(&ctrl->vfeBusPmConfigLocal); + + /* trigger vfe reg update */ + ctrl->vfeStartAckPendingFlag = TRUE; + + /* write bus command to trigger reload of ping pong buffer. */ + ctrl->vfeBusCmdLocal.busPingpongReload = TRUE; + + if (ctrl->vfeModuleEnableLocal.statsEnable == TRUE) { + ctrl->vfeBusCmdLocal.statsPingpongReload = TRUE; + ctrl->vfeStatsPingPongReloadFlag = TRUE; + } + + writel(VFE_REG_UPDATE_TRIGGER, + ctrl->vfebase + VFE_REG_UPDATE_CMD); + + /* program later than the reg update. */ + vfe_reg_bus_cmd(&ctrl->vfeBusCmdLocal); + + if ((in->inputSource == + VFE_START_INPUT_SOURCE_CAMIF) || + (in->inputSource == + VFE_START_INPUT_SOURCE_TESTGEN)) + writel(CAMIF_COMMAND_START, ctrl->vfebase + CAMIF_COMMAND); + + /* start test gen if it is enabled */ + if (ctrl->vfeTestGenStartFlag == TRUE) { + ctrl->vfeTestGenStartFlag = FALSE; + vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_GO); + } + + CDBG("ctrl->axiOutputMode = %d\n", ctrl->axiOutputMode); + if (ctrl->axiOutputMode == VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2) { + /* raw dump mode */ + rawmode = TRUE; + + while (rawmode) { + pmstatus = + readl(ctrl->vfebase + + VFE_BUS_ENC_CBCR_WR_PM_STATS_1); + + if ((pmstatus & VFE_PM_BUF_MAX_CNT_MASK) != 0) + rawmode = FALSE; + } + + vfe_send_msg_no_payload(VFE_MSG_ID_START_ACK); + ctrl->vfeStartAckPendingFlag = FALSE; + } + + spin_lock_irqsave(&ctrl->state_lock, flags); + ctrl->vstate = VFE_STATE_ACTIVE; + spin_unlock_irqrestore(&ctrl->state_lock, flags); +} + +void vfe_la_update(struct vfe_cmd_la_config *in) +{ + int16_t *pTable; + enum VFE_DMI_RAM_SEL dmiRamSel; + int i; + + pTable = in->table; + ctrl->vfeModuleEnableLocal.lumaAdaptationEnable = in->enable; + + /* toggle the bank to be used. */ + ctrl->vfeLaBankSel ^= 1; + + if (ctrl->vfeLaBankSel == 0) + dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK0; + else + dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK1; + + /* configure the DMI_CFG to select right sram */ + vfe_program_dmi_cfg(dmiRamSel); + + for (i = 0; i < VFE_LA_TABLE_LENGTH; i++) { + writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO); + pTable++; + } + + /* After DMI transfer, to make it safe, need to set + * the DMI_CFG to unselect any SRAM */ + writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG); + writel(ctrl->vfeLaBankSel, ctrl->vfebase + VFE_LA_CFG); +} + +void vfe_la_config(struct vfe_cmd_la_config *in) +{ + uint16_t i; + int16_t *pTable; + enum VFE_DMI_RAM_SEL dmiRamSel; + + pTable = in->table; + ctrl->vfeModuleEnableLocal.lumaAdaptationEnable = in->enable; + + if (ctrl->vfeLaBankSel == 0) + dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK0; + else + dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK1; + + /* configure the DMI_CFG to select right sram */ + vfe_program_dmi_cfg(dmiRamSel); + + for (i = 0; i < VFE_LA_TABLE_LENGTH; i++) { + writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO); + pTable++; + } + + /* After DMI transfer, to make it safe, need to set the + * DMI_CFG to unselect any SRAM */ + writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG); + + /* can only be bank 0 or bank 1 for now. */ + writel(ctrl->vfeLaBankSel, ctrl->vfebase + VFE_LA_CFG); + CDBG("VFE Luma adaptation bank selection is 0x%x\n", + *(uint32_t *)&ctrl->vfeLaBankSel); +} + +void vfe_test_gen_start(struct vfe_cmd_test_gen_start *in) +{ + struct VFE_TestGen_ConfigCmdType cmd; + + memset(&cmd, 0, sizeof(cmd)); + + cmd.numFrame = in->numFrame; + cmd.pixelDataSelect = in->pixelDataSelect; + cmd.systematicDataSelect = in->systematicDataSelect; + cmd.pixelDataSize = (uint32_t)in->pixelDataSize; + cmd.hsyncEdge = (uint32_t)in->hsyncEdge; + cmd.vsyncEdge = (uint32_t)in->vsyncEdge; + cmd.imageWidth = in->imageWidth; + cmd.imageHeight = in->imageHeight; + cmd.sofOffset = in->startOfFrameOffset; + cmd.eofNOffset = in->endOfFrameNOffset; + cmd.solOffset = in->startOfLineOffset; + cmd.eolNOffset = in->endOfLineNOffset; + cmd.hBlankInterval = in->hbi; + cmd.vBlankInterval = in->vbl; + cmd.vBlankIntervalEnable = in->vblEnable; + cmd.sofDummy = in->startOfFrameDummyLine; + cmd.eofDummy = in->endOfFrameDummyLine; + cmd.unicolorBarSelect = in->unicolorBarSelect; + cmd.unicolorBarEnable = in->unicolorBarEnable; + cmd.splitEnable = in->colorBarsSplitEnable; + cmd.pixelPattern = (uint32_t)in->colorBarsPixelPattern; + cmd.rotatePeriod = in->colorBarsRotatePeriod; + cmd.randomSeed = in->testGenRandomSeed; + + vfe_prog_hw(ctrl->vfebase + VFE_HW_TESTGEN_CFG, + (uint32_t *) &cmd, sizeof(cmd)); +} + +void vfe_frame_skip_update(struct vfe_cmd_frame_skip_update *in) +{ + struct VFE_FRAME_SKIP_UpdateCmdType cmd; + + cmd.yPattern = in->output1Pattern; + cmd.cbcrPattern = in->output1Pattern; + vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN, + (uint32_t *)&cmd, sizeof(cmd)); + + cmd.yPattern = in->output2Pattern; + cmd.cbcrPattern = in->output2Pattern; + vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN, + (uint32_t *)&cmd, sizeof(cmd)); +} + +void vfe_frame_skip_config(struct vfe_cmd_frame_skip_config *in) +{ + struct vfe_frame_skip_cfg cmd; + memset(&cmd, 0, sizeof(cmd)); + + ctrl->vfeFrameSkip = *in; + + cmd.output2YPeriod = in->output2Period; + cmd.output2CbCrPeriod = in->output2Period; + cmd.output2YPattern = in->output2Pattern; + cmd.output2CbCrPattern = in->output2Pattern; + cmd.output1YPeriod = in->output1Period; + cmd.output1CbCrPeriod = in->output1Period; + cmd.output1YPattern = in->output1Pattern; + cmd.output1CbCrPattern = in->output1Pattern; + + vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG, + (uint32_t *)&cmd, sizeof(cmd)); +} + +void vfe_output_clamp_config(struct vfe_cmd_output_clamp_config *in) +{ + struct vfe_output_clamp_cfg cmd; + memset(&cmd, 0, sizeof(cmd)); + + cmd.yChanMax = in->maxCh0; + cmd.cbChanMax = in->maxCh1; + cmd.crChanMax = in->maxCh2; + + cmd.yChanMin = in->minCh0; + cmd.cbChanMin = in->minCh1; + cmd.crChanMin = in->minCh2; + + vfe_prog_hw(ctrl->vfebase + VFE_CLAMP_MAX_CFG, (uint32_t *)&cmd, + sizeof(cmd)); +} + +void vfe_camif_frame_update(struct vfe_cmds_camif_frame *in) +{ + struct vfe_camifframe_update cmd; + + memset(&cmd, 0, sizeof(cmd)); + + cmd.pixelsPerLine = in->pixelsPerLine; + cmd.linesPerFrame = in->linesPerFrame; + + vfe_prog_hw(ctrl->vfebase + CAMIF_FRAME_CONFIG, (uint32_t *)&cmd, + sizeof(cmd)); +} + +void vfe_color_correction_config( + struct vfe_cmd_color_correction_config *in) +{ + struct vfe_color_correction_cfg cmd; + + memset(&cmd, 0, sizeof(cmd)); + ctrl->vfeModuleEnableLocal.colorCorrectionEnable = in->enable; + + cmd.c0 = in->C0; + cmd.c1 = in->C1; + cmd.c2 = in->C2; + cmd.c3 = in->C3; + cmd.c4 = in->C4; + cmd.c5 = in->C5; + cmd.c6 = in->C6; + cmd.c7 = in->C7; + cmd.c8 = in->C8; + + cmd.k0 = in->K0; + cmd.k1 = in->K1; + cmd.k2 = in->K2; + + cmd.coefQFactor = in->coefQFactor; + + vfe_prog_hw(ctrl->vfebase + VFE_COLOR_CORRECT_COEFF_0, + (uint32_t *)&cmd, sizeof(cmd)); +} + +void vfe_demosaic_abf_update(struct vfe_cmd_demosaic_abf_update *in) +{ +struct vfe_demosaic_cfg cmd; + struct vfe_demosaic_abf_cfg cmdabf; + uint32_t temp; + + memset(&cmd, 0, sizeof(cmd)); + temp = readl(ctrl->vfebase + VFE_DEMOSAIC_CFG); + + cmd = *((struct vfe_demosaic_cfg *)(&temp)); + cmd.abfEnable = in->abfUpdate.enable; + cmd.forceAbfOn = in->abfUpdate.forceOn; + cmd.abfShift = in->abfUpdate.shift; + vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG, + (uint32_t *)&cmd, sizeof(cmd)); + + cmdabf.lpThreshold = in->abfUpdate.lpThreshold; + cmdabf.ratio = in->abfUpdate.ratio; + cmdabf.minValue = in->abfUpdate.min; + cmdabf.maxValue = in->abfUpdate.max; + vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_ABF_CFG_0, + (uint32_t *)&cmdabf, sizeof(cmdabf)); +} + +void vfe_demosaic_bpc_update(struct vfe_cmd_demosaic_bpc_update *in) +{ + struct vfe_demosaic_cfg cmd; + struct vfe_demosaic_bpc_cfg cmdbpc; + uint32_t temp; + + memset(&cmd, 0, sizeof(cmd)); + + temp = readl(ctrl->vfebase + VFE_DEMOSAIC_CFG); + + cmd = *((struct vfe_demosaic_cfg *)(&temp)); + cmd.badPixelCorrEnable = in->bpcUpdate.enable; + cmd.fminThreshold = in->bpcUpdate.fminThreshold; + cmd.fmaxThreshold = in->bpcUpdate.fmaxThreshold; + + vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG, + (uint32_t *)&cmd, sizeof(cmd)); + + cmdbpc.blueDiffThreshold = in->bpcUpdate.blueDiffThreshold; + cmdbpc.redDiffThreshold = in->bpcUpdate.redDiffThreshold; + cmdbpc.greenDiffThreshold = in->bpcUpdate.greenDiffThreshold; + + vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_BPC_CFG_0, + (uint32_t *)&cmdbpc, sizeof(cmdbpc)); +} + +void vfe_demosaic_config(struct vfe_cmd_demosaic_config *in) +{ + struct vfe_demosaic_cfg cmd; + struct vfe_demosaic_bpc_cfg cmd_bpc; + struct vfe_demosaic_abf_cfg cmd_abf; + + memset(&cmd, 0, sizeof(cmd)); + memset(&cmd_bpc, 0, sizeof(cmd_bpc)); + memset(&cmd_abf, 0, sizeof(cmd_abf)); + + ctrl->vfeModuleEnableLocal.demosaicEnable = in->enable; + + cmd.abfEnable = in->abfConfig.enable; + cmd.badPixelCorrEnable = in->bpcConfig.enable; + cmd.forceAbfOn = in->abfConfig.forceOn; + cmd.abfShift = in->abfConfig.shift; + cmd.fminThreshold = in->bpcConfig.fminThreshold; + cmd.fmaxThreshold = in->bpcConfig.fmaxThreshold; + cmd.slopeShift = in->slopeShift; + + vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG, + (uint32_t *)&cmd, sizeof(cmd)); + + cmd_abf.lpThreshold = in->abfConfig.lpThreshold; + cmd_abf.ratio = in->abfConfig.ratio; + cmd_abf.minValue = in->abfConfig.min; + cmd_abf.maxValue = in->abfConfig.max; + + vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_ABF_CFG_0, + (uint32_t *)&cmd_abf, sizeof(cmd_abf)); + + cmd_bpc.blueDiffThreshold = in->bpcConfig.blueDiffThreshold; + cmd_bpc.redDiffThreshold = in->bpcConfig.redDiffThreshold; + cmd_bpc.greenDiffThreshold = in->bpcConfig.greenDiffThreshold; + + vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_BPC_CFG_0, + (uint32_t *)&cmd_bpc, sizeof(cmd_bpc)); +} + +void vfe_demux_channel_gain_update( + struct vfe_cmd_demux_channel_gain_config *in) +{ + struct vfe_demux_cfg cmd; + + memset(&cmd, 0, sizeof(cmd)); + + cmd.ch0EvenGain = in->ch0EvenGain; + cmd.ch0OddGain = in->ch0OddGain; + cmd.ch1Gain = in->ch1Gain; + cmd.ch2Gain = in->ch2Gain; + + vfe_prog_hw(ctrl->vfebase + VFE_DEMUX_GAIN_0, + (uint32_t *)&cmd, sizeof(cmd)); +} + +void vfe_demux_channel_gain_config( + struct vfe_cmd_demux_channel_gain_config *in) +{ + struct vfe_demux_cfg cmd; + + memset(&cmd, 0, sizeof(cmd)); + + cmd.ch0EvenGain = in->ch0EvenGain; + cmd.ch0OddGain = in->ch0OddGain; + cmd.ch1Gain = in->ch1Gain; + cmd.ch2Gain = in->ch2Gain; + + vfe_prog_hw(ctrl->vfebase + VFE_DEMUX_GAIN_0, + (uint32_t *)&cmd, sizeof(cmd)); +} + +void vfe_black_level_update(struct vfe_cmd_black_level_config *in) +{ + struct vfe_blacklevel_cfg cmd; + + memset(&cmd, 0, sizeof(cmd)); + ctrl->vfeModuleEnableLocal.blackLevelCorrectionEnable = in->enable; + + cmd.evenEvenAdjustment = in->evenEvenAdjustment; + cmd.evenOddAdjustment = in->evenOddAdjustment; + cmd.oddEvenAdjustment = in->oddEvenAdjustment; + cmd.oddOddAdjustment = in->oddOddAdjustment; + + vfe_prog_hw(ctrl->vfebase + VFE_BLACK_EVEN_EVEN_VALUE, + (uint32_t *)&cmd, sizeof(cmd)); +} + +void vfe_black_level_config(struct vfe_cmd_black_level_config *in) +{ + struct vfe_blacklevel_cfg cmd; + memset(&cmd, 0, sizeof(cmd)); + + ctrl->vfeModuleEnableLocal.blackLevelCorrectionEnable = in->enable; + + cmd.evenEvenAdjustment = in->evenEvenAdjustment; + cmd.evenOddAdjustment = in->evenOddAdjustment; + cmd.oddEvenAdjustment = in->oddEvenAdjustment; + cmd.oddOddAdjustment = in->oddOddAdjustment; + + vfe_prog_hw(ctrl->vfebase + VFE_BLACK_EVEN_EVEN_VALUE, + (uint32_t *)&cmd, sizeof(cmd)); +} + +void vfe_asf_update(struct vfe_cmd_asf_update *in) +{ + struct vfe_asf_update cmd; + memset(&cmd, 0, sizeof(cmd)); + + ctrl->vfeModuleEnableLocal.asfEnable = in->enable; + + cmd.smoothEnable = in->smoothFilterEnabled; + cmd.sharpMode = in->sharpMode; + cmd.smoothCoeff1 = in->smoothCoefCenter; + cmd.smoothCoeff0 = in->smoothCoefSurr; + cmd.cropEnable = in->cropEnable; + cmd.sharpThresholdE1 = in->sharpThreshE1; + cmd.sharpDegreeK1 = in->sharpK1; + cmd.sharpDegreeK2 = in->sharpK2; + cmd.normalizeFactor = in->normalizeFactor; + cmd.sharpThresholdE2 = in->sharpThreshE2; + cmd.sharpThresholdE3 = in->sharpThreshE3; + cmd.sharpThresholdE4 = in->sharpThreshE4; + cmd.sharpThresholdE5 = in->sharpThreshE5; + cmd.F1Coeff0 = in->filter1Coefficients[0]; + cmd.F1Coeff1 = in->filter1Coefficients[1]; + cmd.F1Coeff2 = in->filter1Coefficients[2]; + cmd.F1Coeff3 = in->filter1Coefficients[3]; + cmd.F1Coeff4 = in->filter1Coefficients[4]; + cmd.F1Coeff5 = in->filter1Coefficients[5]; + cmd.F1Coeff6 = in->filter1Coefficients[6]; + cmd.F1Coeff7 = in->filter1Coefficients[7]; + cmd.F1Coeff8 = in->filter1Coefficients[8]; + cmd.F2Coeff0 = in->filter2Coefficients[0]; + cmd.F2Coeff1 = in->filter2Coefficients[1]; + cmd.F2Coeff2 = in->filter2Coefficients[2]; + cmd.F2Coeff3 = in->filter2Coefficients[3]; + cmd.F2Coeff4 = in->filter2Coefficients[4]; + cmd.F2Coeff5 = in->filter2Coefficients[5]; + cmd.F2Coeff6 = in->filter2Coefficients[6]; + cmd.F2Coeff7 = in->filter2Coefficients[7]; + cmd.F2Coeff8 = in->filter2Coefficients[8]; + + vfe_prog_hw(ctrl->vfebase + VFE_ASF_CFG, + (uint32_t *)&cmd, sizeof(cmd)); +} + +void vfe_asf_config(struct vfe_cmd_asf_config *in) +{ + struct vfe_asf_update cmd; + struct vfe_asfcrop_cfg cmd2; + + memset(&cmd, 0, sizeof(cmd)); + memset(&cmd2, 0, sizeof(cmd2)); + + ctrl->vfeModuleEnableLocal.asfEnable = in->enable; + + cmd.smoothEnable = in->smoothFilterEnabled; + cmd.sharpMode = in->sharpMode; + cmd.smoothCoeff0 = in->smoothCoefCenter; + cmd.smoothCoeff1 = in->smoothCoefSurr; + cmd.cropEnable = in->cropEnable; + cmd.sharpThresholdE1 = in->sharpThreshE1; + cmd.sharpDegreeK1 = in->sharpK1; + cmd.sharpDegreeK2 = in->sharpK2; + cmd.normalizeFactor = in->normalizeFactor; + cmd.sharpThresholdE2 = in->sharpThreshE2; + cmd.sharpThresholdE3 = in->sharpThreshE3; + cmd.sharpThresholdE4 = in->sharpThreshE4; + cmd.sharpThresholdE5 = in->sharpThreshE5; + cmd.F1Coeff0 = in->filter1Coefficients[0]; + cmd.F1Coeff1 = in->filter1Coefficients[1]; + cmd.F1Coeff2 = in->filter1Coefficients[2]; + cmd.F1Coeff3 = in->filter1Coefficients[3]; + cmd.F1Coeff4 = in->filter1Coefficients[4]; + cmd.F1Coeff5 = in->filter1Coefficients[5]; + cmd.F1Coeff6 = in->filter1Coefficients[6]; + cmd.F1Coeff7 = in->filter1Coefficients[7]; + cmd.F1Coeff8 = in->filter1Coefficients[8]; + cmd.F2Coeff0 = in->filter2Coefficients[0]; + cmd.F2Coeff1 = in->filter2Coefficients[1]; + cmd.F2Coeff2 = in->filter2Coefficients[2]; + cmd.F2Coeff3 = in->filter2Coefficients[3]; + cmd.F2Coeff4 = in->filter2Coefficients[4]; + cmd.F2Coeff5 = in->filter2Coefficients[5]; + cmd.F2Coeff6 = in->filter2Coefficients[6]; + cmd.F2Coeff7 = in->filter2Coefficients[7]; + cmd.F2Coeff8 = in->filter2Coefficients[8]; + + vfe_prog_hw(ctrl->vfebase + VFE_ASF_CFG, + (uint32_t *)&cmd, sizeof(cmd)); + + cmd2.firstLine = in->cropFirstLine; + cmd2.lastLine = in->cropLastLine; + cmd2.firstPixel = in->cropFirstPixel; + cmd2.lastPixel = in->cropLastPixel; + + vfe_prog_hw(ctrl->vfebase + VFE_ASF_CROP_WIDTH_CFG, + (uint32_t *)&cmd2, sizeof(cmd2)); +} + +void vfe_white_balance_config(struct vfe_cmd_white_balance_config *in) +{ + struct vfe_wb_cfg cmd; + memset(&cmd, 0, sizeof(cmd)); + + ctrl->vfeModuleEnableLocal.whiteBalanceEnable = + in->enable; + + cmd.ch0Gain = in->ch0Gain; + cmd.ch1Gain = in->ch1Gain; + cmd.ch2Gain = in->ch2Gain; + + vfe_prog_hw(ctrl->vfebase + VFE_WB_CFG, + (uint32_t *)&cmd, sizeof(cmd)); +} + +void vfe_chroma_sup_config(struct vfe_cmd_chroma_suppression_config *in) +{ + struct vfe_chroma_suppress_cfg cmd; + memset(&cmd, 0, sizeof(cmd)); + + ctrl->vfeModuleEnableLocal.chromaSuppressionEnable = in->enable; + + cmd.m1 = in->m1; + cmd.m3 = in->m3; + cmd.n1 = in->n1; + cmd.n3 = in->n3; + cmd.mm1 = in->mm1; + cmd.nn1 = in->nn1; + + vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_SUPPRESS_CFG_0, + (uint32_t *)&cmd, sizeof(cmd)); +} + +void vfe_roll_off_config(struct vfe_cmd_roll_off_config *in) +{ + struct vfe_rolloff_cfg cmd; + memset(&cmd, 0, sizeof(cmd)); + + ctrl->vfeModuleEnableLocal.lensRollOffEnable = in->enable; + + cmd.gridWidth = in->gridWidth; + cmd.gridHeight = in->gridHeight; + cmd.yDelta = in->yDelta; + cmd.gridX = in->gridXIndex; + cmd.gridY = in->gridYIndex; + cmd.pixelX = in->gridPixelXIndex; + cmd.pixelY = in->gridPixelYIndex; + cmd.yDeltaAccum = in->yDeltaAccum; + + vfe_prog_hw(ctrl->vfebase + VFE_ROLLOFF_CFG_0, + (uint32_t *)&cmd, sizeof(cmd)); + + vfe_write_lens_roll_off_table(in); +} + +void vfe_chroma_subsample_config( + struct vfe_cmd_chroma_subsample_config *in) +{ + struct vfe_chromasubsample_cfg cmd; + memset(&cmd, 0, sizeof(cmd)); + + ctrl->vfeModuleEnableLocal.chromaSubsampleEnable = in->enable; + + cmd.hCositedPhase = in->hCositedPhase; + cmd.vCositedPhase = in->vCositedPhase; + cmd.hCosited = in->hCosited; + cmd.vCosited = in->vCosited; + cmd.hsubSampleEnable = in->hsubSampleEnable; + cmd.vsubSampleEnable = in->vsubSampleEnable; + cmd.cropEnable = in->cropEnable; + cmd.cropWidthLastPixel = in->cropWidthLastPixel; + cmd.cropWidthFirstPixel = in->cropWidthFirstPixel; + cmd.cropHeightLastLine = in->cropHeightLastLine; + cmd.cropHeightFirstLine = in->cropHeightFirstLine; + + vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_SUBSAMPLE_CFG, + (uint32_t *)&cmd, sizeof(cmd)); +} + +void vfe_chroma_enhan_config(struct vfe_cmd_chroma_enhan_config *in) +{ + struct vfe_chroma_enhance_cfg cmd; + struct vfe_color_convert_cfg cmd2; + + memset(&cmd, 0, sizeof(cmd)); + memset(&cmd2, 0, sizeof(cmd2)); + + ctrl->vfeModuleEnableLocal.chromaEnhanEnable = in->enable; + + cmd.ap = in->ap; + cmd.am = in->am; + cmd.bp = in->bp; + cmd.bm = in->bm; + cmd.cp = in->cp; + cmd.cm = in->cm; + cmd.dp = in->dp; + cmd.dm = in->dm; + cmd.kcb = in->kcb; + cmd.kcr = in->kcr; + + cmd2.v0 = in->RGBtoYConversionV0; + cmd2.v1 = in->RGBtoYConversionV1; + cmd2.v2 = in->RGBtoYConversionV2; + cmd2.ConvertOffset = in->RGBtoYConversionOffset; + + vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_ENHAN_A, + (uint32_t *)&cmd, sizeof(cmd)); + + vfe_prog_hw(ctrl->vfebase + VFE_COLOR_CONVERT_COEFF_0, + (uint32_t *)&cmd2, sizeof(cmd2)); +} + +void vfe_scaler2cbcr_config(struct vfe_cmd_scaler2_config *in) +{ + struct vfe_scaler2_cfg cmd; + + memset(&cmd, 0, sizeof(cmd)); + + ctrl->vfeModuleEnableLocal.scaler2CbcrEnable = in->enable; + + cmd.hEnable = in->hconfig.enable; + cmd.vEnable = in->vconfig.enable; + cmd.inWidth = in->hconfig.inputSize; + cmd.outWidth = in->hconfig.outputSize; + cmd.horizPhaseMult = in->hconfig.phaseMultiplicationFactor; + cmd.horizInterResolution = in->hconfig.interpolationResolution; + cmd.inHeight = in->vconfig.inputSize; + cmd.outHeight = in->vconfig.outputSize; + cmd.vertPhaseMult = in->vconfig.phaseMultiplicationFactor; + cmd.vertInterResolution = in->vconfig.interpolationResolution; + + vfe_prog_hw(ctrl->vfebase + VFE_SCALE_CBCR_CFG, + (uint32_t *)&cmd, sizeof(cmd)); +} + +void vfe_scaler2y_config(struct vfe_cmd_scaler2_config *in) +{ + struct vfe_scaler2_cfg cmd; + + memset(&cmd, 0, sizeof(cmd)); + + ctrl->vfeModuleEnableLocal.scaler2YEnable = in->enable; + + cmd.hEnable = in->hconfig.enable; + cmd.vEnable = in->vconfig.enable; + cmd.inWidth = in->hconfig.inputSize; + cmd.outWidth = in->hconfig.outputSize; + cmd.horizPhaseMult = in->hconfig.phaseMultiplicationFactor; + cmd.horizInterResolution = in->hconfig.interpolationResolution; + cmd.inHeight = in->vconfig.inputSize; + cmd.outHeight = in->vconfig.outputSize; + cmd.vertPhaseMult = in->vconfig.phaseMultiplicationFactor; + cmd.vertInterResolution = in->vconfig.interpolationResolution; + + vfe_prog_hw(ctrl->vfebase + VFE_SCALE_Y_CFG, + (uint32_t *)&cmd, sizeof(cmd)); +} + +void vfe_main_scaler_config(struct vfe_cmd_main_scaler_config *in) +{ + struct vfe_main_scaler_cfg cmd; + + memset(&cmd, 0, sizeof(cmd)); + + ctrl->vfeModuleEnableLocal.mainScalerEnable = in->enable; + + cmd.hEnable = in->hconfig.enable; + cmd.vEnable = in->vconfig.enable; + cmd.inWidth = in->hconfig.inputSize; + cmd.outWidth = in->hconfig.outputSize; + cmd.horizPhaseMult = in->hconfig.phaseMultiplicationFactor; + cmd.horizInterResolution = in->hconfig.interpolationResolution; + cmd.horizMNInit = in->MNInitH.MNCounterInit; + cmd.horizPhaseInit = in->MNInitH.phaseInit; + cmd.inHeight = in->vconfig.inputSize; + cmd.outHeight = in->vconfig.outputSize; + cmd.vertPhaseMult = in->vconfig.phaseMultiplicationFactor; + cmd.vertInterResolution = in->vconfig.interpolationResolution; + cmd.vertMNInit = in->MNInitV.MNCounterInit; + cmd.vertPhaseInit = in->MNInitV.phaseInit; + + vfe_prog_hw(ctrl->vfebase + VFE_SCALE_CFG, + (uint32_t *)&cmd, sizeof(cmd)); +} + +void vfe_stats_wb_exp_stop(void) +{ + ctrl->vfeStatsCmdLocal.axwEnable = FALSE; + ctrl->vfeImaskLocal.awbPingpongIrq = FALSE; +} + +void vfe_stats_update_wb_exp(struct vfe_cmd_stats_wb_exp_update *in) +{ + struct vfe_statsawb_update cmd; + struct vfe_statsawbae_update cmd2; + + memset(&cmd, 0, sizeof(cmd)); + memset(&cmd2, 0, sizeof(cmd2)); + + cmd.m1 = in->awbMCFG[0]; + cmd.m2 = in->awbMCFG[1]; + cmd.m3 = in->awbMCFG[2]; + cmd.m4 = in->awbMCFG[3]; + cmd.c1 = in->awbCCFG[0]; + cmd.c2 = in->awbCCFG[1]; + cmd.c3 = in->awbCCFG[2]; + cmd.c4 = in->awbCCFG[3]; + vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWB_MCFG, + (uint32_t *)&cmd, sizeof(cmd)); + + cmd2.aeRegionCfg = in->wbExpRegions; + cmd2.aeSubregionCfg = in->wbExpSubRegion; + cmd2.awbYMin = in->awbYMin; + cmd2.awbYMax = in->awbYMax; + vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWBAE_CFG, + (uint32_t *)&cmd2, sizeof(cmd2)); +} + +void vfe_stats_update_af(struct vfe_cmd_stats_af_update *in) +{ + struct vfe_statsaf_update cmd; + memset(&cmd, 0, sizeof(cmd)); + + cmd.windowVOffset = in->windowVOffset; + cmd.windowHOffset = in->windowHOffset; + cmd.windowMode = in->windowMode; + cmd.windowHeight = in->windowHeight; + cmd.windowWidth = in->windowWidth; + + vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_CFG, + (uint32_t *)&cmd, sizeof(cmd)); +} + +void vfe_stats_start_wb_exp(struct vfe_cmd_stats_wb_exp_start *in) +{ + struct vfe_statsawb_update cmd; + struct vfe_statsawbae_update cmd2; + struct vfe_statsaxw_hdr_cfg cmd3; + + ctrl->vfeStatsCmdLocal.axwEnable = in->enable; + ctrl->vfeImaskLocal.awbPingpongIrq = TRUE; + + memset(&cmd, 0, sizeof(cmd)); + memset(&cmd2, 0, sizeof(cmd2)); + memset(&cmd3, 0, sizeof(cmd3)); + + cmd.m1 = in->awbMCFG[0]; + cmd.m2 = in->awbMCFG[1]; + cmd.m3 = in->awbMCFG[2]; + cmd.m4 = in->awbMCFG[3]; + cmd.c1 = in->awbCCFG[0]; + cmd.c2 = in->awbCCFG[1]; + cmd.c3 = in->awbCCFG[2]; + cmd.c4 = in->awbCCFG[3]; + vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWB_MCFG, + (uint32_t *)&cmd, sizeof(cmd)); + + cmd2.aeRegionCfg = in->wbExpRegions; + cmd2.aeSubregionCfg = in->wbExpSubRegion; + cmd2.awbYMin = in->awbYMin; + cmd2.awbYMax = in->awbYMax; + vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWBAE_CFG, + (uint32_t *)&cmd2, sizeof(cmd2)); + + cmd3.axwHeader = in->axwHeader; + vfe_prog_hw(ctrl->vfebase + VFE_STATS_AXW_HEADER, + (uint32_t *)&cmd3, sizeof(cmd3)); +} + +void vfe_stats_start_af(struct vfe_cmd_stats_af_start *in) +{ + struct vfe_statsaf_update cmd; + struct vfe_statsaf_cfg cmd2; + + memset(&cmd, 0, sizeof(cmd)); + memset(&cmd2, 0, sizeof(cmd2)); + +ctrl->vfeStatsCmdLocal.autoFocusEnable = in->enable; +ctrl->vfeImaskLocal.afPingpongIrq = TRUE; + + cmd.windowVOffset = in->windowVOffset; + cmd.windowHOffset = in->windowHOffset; + cmd.windowMode = in->windowMode; + cmd.windowHeight = in->windowHeight; + cmd.windowWidth = in->windowWidth; + + vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_CFG, + (uint32_t *)&cmd, sizeof(cmd)); + + cmd2.a00 = in->highPassCoef[0]; + cmd2.a04 = in->highPassCoef[1]; + cmd2.a20 = in->highPassCoef[2]; + cmd2.a21 = in->highPassCoef[3]; + cmd2.a22 = in->highPassCoef[4]; + cmd2.a23 = in->highPassCoef[5]; + cmd2.a24 = in->highPassCoef[6]; + cmd2.fvMax = in->metricMax; + cmd2.fvMetric = in->metricSelection; + cmd2.afHeader = in->bufferHeader; + cmd2.entry00 = in->gridForMultiWindows[0]; + cmd2.entry01 = in->gridForMultiWindows[1]; + cmd2.entry02 = in->gridForMultiWindows[2]; + cmd2.entry03 = in->gridForMultiWindows[3]; + cmd2.entry10 = in->gridForMultiWindows[4]; + cmd2.entry11 = in->gridForMultiWindows[5]; + cmd2.entry12 = in->gridForMultiWindows[6]; + cmd2.entry13 = in->gridForMultiWindows[7]; + cmd2.entry20 = in->gridForMultiWindows[8]; + cmd2.entry21 = in->gridForMultiWindows[9]; + cmd2.entry22 = in->gridForMultiWindows[10]; + cmd2.entry23 = in->gridForMultiWindows[11]; + cmd2.entry30 = in->gridForMultiWindows[12]; + cmd2.entry31 = in->gridForMultiWindows[13]; + cmd2.entry32 = in->gridForMultiWindows[14]; + cmd2.entry33 = in->gridForMultiWindows[15]; + + vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_GRID_0, + (uint32_t *)&cmd2, sizeof(cmd2)); +} + +void vfe_stats_setting(struct vfe_cmd_stats_setting *in) +{ + struct vfe_statsframe cmd1; + struct vfe_busstats_wrprio cmd2; + + memset(&cmd1, 0, sizeof(cmd1)); + memset(&cmd2, 0, sizeof(cmd2)); + + ctrl->afStatsControl.addressBuffer[0] = in->afBuffer[0]; + ctrl->afStatsControl.addressBuffer[1] = in->afBuffer[1]; + ctrl->afStatsControl.nextFrameAddrBuf = in->afBuffer[2]; + + ctrl->awbStatsControl.addressBuffer[0] = in->awbBuffer[0]; + ctrl->awbStatsControl.addressBuffer[1] = in->awbBuffer[1]; + ctrl->awbStatsControl.nextFrameAddrBuf = in->awbBuffer[2]; + + cmd1.lastPixel = in->frameHDimension; + cmd1.lastLine = in->frameVDimension; + vfe_prog_hw(ctrl->vfebase + VFE_STATS_FRAME_SIZE, + (uint32_t *)&cmd1, sizeof(cmd1)); + + cmd2.afBusPriority = in->afBusPriority; + cmd2.awbBusPriority = in->awbBusPriority; + cmd2.histBusPriority = in->histBusPriority; + cmd2.afBusPriorityEn = in->afBusPrioritySelection; + cmd2.awbBusPriorityEn = in->awbBusPrioritySelection; + cmd2.histBusPriorityEn = in->histBusPrioritySelection; + + vfe_prog_hw(ctrl->vfebase + VFE_BUS_STATS_WR_PRIORITY, + (uint32_t *)&cmd2, sizeof(cmd2)); + + /* Program the bus ping pong address for statistics modules. */ + writel(in->afBuffer[0], ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR); + writel(in->afBuffer[1], ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR); + writel(in->awbBuffer[0], + ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR); + writel(in->awbBuffer[1], + ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR); + writel(in->histBuffer[0], + ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PING_ADDR); + writel(in->histBuffer[1], + ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PONG_ADDR); +} + +void vfe_axi_input_config(struct vfe_cmd_axi_input_config *in) +{ + struct VFE_AxiInputCmdType cmd; + uint32_t xSizeWord, axiRdUnpackPattern; + uint8_t axiInputPpw; + uint32_t busPingpongRdIrqEnable; + + ctrl->vfeImaskLocal.rdPingpongIrq = TRUE; + + switch (in->pixelSize) { + case VFE_RAW_PIXEL_DATA_SIZE_10BIT: + ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_10BIT; + break; + + case VFE_RAW_PIXEL_DATA_SIZE_12BIT: + ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_12BIT; + break; + + case VFE_RAW_PIXEL_DATA_SIZE_8BIT: + default: + ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_8BIT; + break; + } + + memset(&cmd, 0, sizeof(cmd)); + + switch (in->pixelSize) { + case VFE_RAW_PIXEL_DATA_SIZE_10BIT: + axiInputPpw = 6; + axiRdUnpackPattern = 0xD43210; + break; + + case VFE_RAW_PIXEL_DATA_SIZE_12BIT: + axiInputPpw = 5; + axiRdUnpackPattern = 0xC3210; + break; + + case VFE_RAW_PIXEL_DATA_SIZE_8BIT: + default: + axiInputPpw = 8; + axiRdUnpackPattern = 0xF6543210; + break; + } + + xSizeWord = + ((((in->xOffset % axiInputPpw) + in->xSize) + + (axiInputPpw-1)) / axiInputPpw) - 1; + + cmd.stripeStartAddr0 = in->fragAddr[0]; + cmd.stripeStartAddr1 = in->fragAddr[1]; + cmd.stripeStartAddr2 = in->fragAddr[2]; + cmd.stripeStartAddr3 = in->fragAddr[3]; + cmd.ySize = in->ySize; + cmd.yOffsetDelta = 0; + cmd.xSizeWord = xSizeWord; + cmd.burstLength = 1; + cmd.NumOfRows = in->numOfRows; + cmd.RowIncrement = + (in->rowIncrement + (axiInputPpw-1))/axiInputPpw; + cmd.mainUnpackHeight = in->ySize; + cmd.mainUnpackWidth = in->xSize - 1; + cmd.mainUnpackHbiSel = (uint32_t)in->unpackHbi; + cmd.mainUnpackPhase = in->unpackPhase; + cmd.unpackPattern = axiRdUnpackPattern; + cmd.padLeft = in->padRepeatCountLeft; + cmd.padRight = in->padRepeatCountRight; + cmd.padTop = in->padRepeatCountTop; + cmd.padBottom = in->padRepeatCountBottom; + cmd.leftUnpackPattern0 = in->padLeftComponentSelectCycle0; + cmd.leftUnpackPattern1 = in->padLeftComponentSelectCycle1; + cmd.leftUnpackPattern2 = in->padLeftComponentSelectCycle2; + cmd.leftUnpackPattern3 = in->padLeftComponentSelectCycle3; + cmd.leftUnpackStop0 = in->padLeftStopCycle0; + cmd.leftUnpackStop1 = in->padLeftStopCycle1; + cmd.leftUnpackStop2 = in->padLeftStopCycle2; + cmd.leftUnpackStop3 = in->padLeftStopCycle3; + cmd.rightUnpackPattern0 = in->padRightComponentSelectCycle0; + cmd.rightUnpackPattern1 = in->padRightComponentSelectCycle1; + cmd.rightUnpackPattern2 = in->padRightComponentSelectCycle2; + cmd.rightUnpackPattern3 = in->padRightComponentSelectCycle3; + cmd.rightUnpackStop0 = in->padRightStopCycle0; + cmd.rightUnpackStop1 = in->padRightStopCycle1; + cmd.rightUnpackStop2 = in->padRightStopCycle2; + cmd.rightUnpackStop3 = in->padRightStopCycle3; + cmd.topUnapckPattern = in->padTopLineCount; + cmd.bottomUnapckPattern = in->padBottomLineCount; + + /* program vfe_bus_cfg */ + vfe_prog_hw(ctrl->vfebase + VFE_BUS_STRIPE_RD_ADDR_0, + (uint32_t *)&cmd, sizeof(cmd)); + + /* hacking code, put it to default value */ + busPingpongRdIrqEnable = 0xf; + + writel(busPingpongRdIrqEnable, + ctrl->vfebase + VFE_BUS_PINGPONG_IRQ_EN); +} + +void vfe_stats_config(struct vfe_cmd_stats_setting *in) +{ + ctrl->afStatsControl.addressBuffer[0] = in->afBuffer[0]; + ctrl->afStatsControl.addressBuffer[1] = in->afBuffer[1]; + ctrl->afStatsControl.nextFrameAddrBuf = in->afBuffer[2]; + + ctrl->awbStatsControl.addressBuffer[0] = in->awbBuffer[0]; + ctrl->awbStatsControl.addressBuffer[1] = in->awbBuffer[1]; + ctrl->awbStatsControl.nextFrameAddrBuf = in->awbBuffer[2]; + + vfe_stats_setting(in); +} + +void vfe_axi_output_config( + struct vfe_cmd_axi_output_config *in) +{ + /* local variable */ + uint32_t *pcircle; + uint32_t *pdest; + uint32_t *psrc; + uint8_t i; + uint8_t fcnt; + uint16_t axioutpw = 8; + + /* parameters check, condition and usage mode check */ + ctrl->encPath.fragCount = in->output2.fragmentCount; + if (ctrl->encPath.fragCount > 1) + ctrl->encPath.multiFrag = TRUE; + + ctrl->viewPath.fragCount = in->output1.fragmentCount; + if (ctrl->viewPath.fragCount > 1) + ctrl->viewPath.multiFrag = TRUE; + + /* VFE_BUS_CFG. raw data size */ + ctrl->vfeBusConfigLocal.rawPixelDataSize = in->outputDataSize; + + switch (in->outputDataSize) { + case VFE_RAW_PIXEL_DATA_SIZE_8BIT: + axioutpw = 8; + break; + + case VFE_RAW_PIXEL_DATA_SIZE_10BIT: + axioutpw = 6; + break; + + case VFE_RAW_PIXEL_DATA_SIZE_12BIT: + axioutpw = 5; + break; + } + + ctrl->axiOutputMode = in->outputMode; + + CDBG("axiOutputMode = %d\n", ctrl->axiOutputMode); + + switch (ctrl->axiOutputMode) { + case VFE_AXI_OUTPUT_MODE_Output1: { + ctrl->vfeCamifConfigLocal.camif2BusEnable = FALSE; + ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE; + ctrl->vfeBusConfigLocal.rawWritePathSelect = + VFE_RAW_OUTPUT_DISABLED; + + ctrl->encPath.pathEnabled = FALSE; + ctrl->vfeImaskLocal.encIrq = FALSE; + ctrl->vfeIrqCompositeMaskLocal.encIrqComMask = + VFE_COMP_IRQ_BOTH_Y_CBCR; + + ctrl->vfeBusConfigLocal.encYWrPathEn = FALSE; + ctrl->vfeBusConfigLocal.encCbcrWrPathEn = FALSE; + ctrl->viewPath.pathEnabled = TRUE; + ctrl->vfeImaskLocal.viewIrq = TRUE; + ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask = + VFE_COMP_IRQ_BOTH_Y_CBCR; + + ctrl->vfeBusConfigLocal.viewYWrPathEn = TRUE; + ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = TRUE; + + if (ctrl->vfeBusConfigLocal.encYWrPathEn && + ctrl->encPath.multiFrag) + ctrl->vfeImaskLocal.encYPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn && + ctrl->encPath.multiFrag) + ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.viewYWrPathEn && + ctrl->viewPath.multiFrag) + ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn && + ctrl->viewPath.multiFrag) + ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE; + } /* VFE_AXI_OUTPUT_MODE_Output1 */ + break; + + case VFE_AXI_OUTPUT_MODE_Output2: { + ctrl->vfeCamifConfigLocal.camif2BusEnable = FALSE; + ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE; + ctrl->vfeBusConfigLocal.rawWritePathSelect = + VFE_RAW_OUTPUT_DISABLED; + + ctrl->encPath.pathEnabled = TRUE; + ctrl->vfeImaskLocal.encIrq = TRUE; + ctrl->vfeIrqCompositeMaskLocal.encIrqComMask = + VFE_COMP_IRQ_BOTH_Y_CBCR; + + ctrl->vfeBusConfigLocal.encYWrPathEn = TRUE; + ctrl->vfeBusConfigLocal.encCbcrWrPathEn = TRUE; + + ctrl->viewPath.pathEnabled = FALSE; + ctrl->vfeImaskLocal.viewIrq = FALSE; + ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask = + VFE_COMP_IRQ_BOTH_Y_CBCR; + + ctrl->vfeBusConfigLocal.viewYWrPathEn = FALSE; + ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = FALSE; + + if (ctrl->vfeBusConfigLocal.encYWrPathEn && + ctrl->encPath.multiFrag) + ctrl->vfeImaskLocal.encYPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn && + ctrl->encPath.multiFrag) + ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.viewYWrPathEn && + ctrl->viewPath.multiFrag) + ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn && + ctrl->viewPath.multiFrag) + ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE; + } /* VFE_AXI_OUTPUT_MODE_Output2 */ + break; + + case VFE_AXI_OUTPUT_MODE_Output1AndOutput2: { + ctrl->vfeCamifConfigLocal.camif2BusEnable = FALSE; + ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE; + ctrl->vfeBusConfigLocal.rawWritePathSelect = + VFE_RAW_OUTPUT_DISABLED; + + ctrl->encPath.pathEnabled = TRUE; + ctrl->vfeImaskLocal.encIrq = TRUE; + ctrl->vfeIrqCompositeMaskLocal.encIrqComMask = + VFE_COMP_IRQ_BOTH_Y_CBCR; + + ctrl->vfeBusConfigLocal.encYWrPathEn = TRUE; + ctrl->vfeBusConfigLocal.encCbcrWrPathEn = TRUE; + ctrl->viewPath.pathEnabled = TRUE; + ctrl->vfeImaskLocal.viewIrq = TRUE; + ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask = + VFE_COMP_IRQ_BOTH_Y_CBCR; + + ctrl->vfeBusConfigLocal.viewYWrPathEn = TRUE; + ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = TRUE; + + if (ctrl->vfeBusConfigLocal.encYWrPathEn && + ctrl->encPath.multiFrag) + ctrl->vfeImaskLocal.encYPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn && + ctrl->encPath.multiFrag) + ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.viewYWrPathEn && + ctrl->viewPath.multiFrag) + ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn && + ctrl->viewPath.multiFrag) + ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE; + } /* VFE_AXI_OUTPUT_MODE_Output1AndOutput2 */ + break; + + case VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2: { + /* For raw snapshot, we need both ping and pong buffer + * initialized to the same address. Otherwise, if we + * leave the pong buffer to NULL, there will be axi_error. + * Note that ideally we should deal with this at upper layer, + * which is in msm_vfe8x.c */ + if (!in->output2.outputCbcr.outFragments[1][0]) { + in->output2.outputCbcr.outFragments[1][0] = + in->output2.outputCbcr.outFragments[0][0]; + } + + ctrl->vfeCamifConfigLocal.camif2BusEnable = TRUE; + ctrl->vfeCamifConfigLocal.camif2OutputEnable = FALSE; + ctrl->vfeBusConfigLocal.rawWritePathSelect = + VFE_RAW_OUTPUT_ENC_CBCR_PATH; + + ctrl->encPath.pathEnabled = TRUE; + ctrl->vfeImaskLocal.encIrq = TRUE; + ctrl->vfeIrqCompositeMaskLocal.encIrqComMask = + VFE_COMP_IRQ_CBCR_ONLY; + + ctrl->vfeBusConfigLocal.encYWrPathEn = FALSE; + ctrl->vfeBusConfigLocal.encCbcrWrPathEn = TRUE; + + ctrl->viewPath.pathEnabled = FALSE; + ctrl->vfeImaskLocal.viewIrq = FALSE; + ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask = + VFE_COMP_IRQ_BOTH_Y_CBCR; + + ctrl->vfeBusConfigLocal.viewYWrPathEn = FALSE; + ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = FALSE; + + if (ctrl->vfeBusConfigLocal.encYWrPathEn && + ctrl->encPath.multiFrag) + ctrl->vfeImaskLocal.encYPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn && + ctrl->encPath.multiFrag) + ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.viewYWrPathEn && + ctrl->viewPath.multiFrag) + ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn && + ctrl->viewPath.multiFrag) + ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE; + } /* VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2 */ + break; + + case VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1: { + ctrl->vfeCamifConfigLocal.camif2BusEnable = TRUE; + ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE; + ctrl->vfeBusConfigLocal.rawWritePathSelect = + VFE_RAW_OUTPUT_VIEW_CBCR_PATH; + + ctrl->encPath.pathEnabled = TRUE; + ctrl->vfeImaskLocal.encIrq = TRUE; + ctrl->vfeIrqCompositeMaskLocal.encIrqComMask = + VFE_COMP_IRQ_BOTH_Y_CBCR; + + ctrl->vfeBusConfigLocal.encYWrPathEn = TRUE; + ctrl->vfeBusConfigLocal.encCbcrWrPathEn = TRUE; + + ctrl->viewPath.pathEnabled = TRUE; + ctrl->vfeImaskLocal.viewIrq = TRUE; + ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask = + VFE_COMP_IRQ_CBCR_ONLY; + + ctrl->vfeBusConfigLocal.viewYWrPathEn = FALSE; + ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = TRUE; + + if (ctrl->vfeBusConfigLocal.encYWrPathEn && + ctrl->encPath.multiFrag) + ctrl->vfeImaskLocal.encYPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn && + ctrl->encPath.multiFrag) + ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.viewYWrPathEn && + ctrl->viewPath.multiFrag) + ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn && + ctrl->viewPath.multiFrag) + ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE; + } /* VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1 */ + break; + + case VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2: { + ctrl->vfeCamifConfigLocal.camif2BusEnable = TRUE; + ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE; + ctrl->vfeBusConfigLocal.rawWritePathSelect = + VFE_RAW_OUTPUT_ENC_CBCR_PATH; + + ctrl->encPath.pathEnabled = TRUE; + ctrl->vfeImaskLocal.encIrq = TRUE; + ctrl->vfeIrqCompositeMaskLocal.encIrqComMask = + VFE_COMP_IRQ_CBCR_ONLY; + + ctrl->vfeBusConfigLocal.encYWrPathEn = FALSE; + ctrl->vfeBusConfigLocal.encCbcrWrPathEn = TRUE; + + ctrl->viewPath.pathEnabled = TRUE; + ctrl->vfeImaskLocal.viewIrq = TRUE; + + ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask = + VFE_COMP_IRQ_BOTH_Y_CBCR; + + ctrl->vfeBusConfigLocal.viewYWrPathEn = TRUE; + ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = TRUE; + + if (ctrl->vfeBusConfigLocal.encYWrPathEn && + ctrl->encPath.multiFrag) + ctrl->vfeImaskLocal.encYPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn && + ctrl->encPath.multiFrag) + ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.viewYWrPathEn && + ctrl->viewPath.multiFrag) + ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE; + + if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn && + ctrl->viewPath.multiFrag) + ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE; + } /* VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2 */ + break; + + case VFE_AXI_LAST_OUTPUT_MODE_ENUM: + break; + } /* switch */ + + /* Save the addresses for each path. */ + /* output2 path */ + fcnt = ctrl->encPath.fragCount; + + pcircle = ctrl->encPath.yPath.addressBuffer; + pdest = ctrl->encPath.nextFrameAddrBuf; + + psrc = &(in->output2.outputY.outFragments[0][0]); + for (i = 0; i < fcnt; i++) + *pcircle++ = *psrc++; + + psrc = &(in->output2.outputY.outFragments[1][0]); + for (i = 0; i < fcnt; i++) + *pcircle++ = *psrc++; + + psrc = &(in->output2.outputY.outFragments[2][0]); + for (i = 0; i < fcnt; i++) + *pdest++ = *psrc++; + + pcircle = ctrl->encPath.cbcrPath.addressBuffer; + + psrc = &(in->output2.outputCbcr.outFragments[0][0]); + for (i = 0; i < fcnt; i++) + *pcircle++ = *psrc++; + + psrc = &(in->output2.outputCbcr.outFragments[1][0]); + for (i = 0; i < fcnt; i++) + *pcircle++ = *psrc++; + + psrc = &(in->output2.outputCbcr.outFragments[2][0]); + for (i = 0; i < fcnt; i++) + *pdest++ = *psrc++; + + vfe_set_bus_pipo_addr(&ctrl->viewPath, &ctrl->encPath); + + ctrl->encPath.ackPending = FALSE; + ctrl->encPath.currentFrame = ping; + ctrl->encPath.whichOutputPath = 1; + ctrl->encPath.yPath.fragIndex = 2; + ctrl->encPath.cbcrPath.fragIndex = 2; + ctrl->encPath.yPath.hwCurrentFlag = ping; + ctrl->encPath.cbcrPath.hwCurrentFlag = ping; + + /* output1 path */ + pcircle = ctrl->viewPath.yPath.addressBuffer; + pdest = ctrl->viewPath.nextFrameAddrBuf; + fcnt = ctrl->viewPath.fragCount; + + psrc = &(in->output1.outputY.outFragments[0][0]); + for (i = 0; i < fcnt; i++) + *pcircle++ = *psrc++; + + psrc = &(in->output1.outputY.outFragments[1][0]); + for (i = 0; i < fcnt; i++) + *pcircle++ = *psrc++; + + psrc = &(in->output1.outputY.outFragments[2][0]); + for (i = 0; i < fcnt; i++) + *pdest++ = *psrc++; + + pcircle = ctrl->viewPath.cbcrPath.addressBuffer; + + psrc = &(in->output1.outputCbcr.outFragments[0][0]); + for (i = 0; i < fcnt; i++) + *pcircle++ = *psrc++; + + psrc = &(in->output1.outputCbcr.outFragments[1][0]); + for (i = 0; i < fcnt; i++) + *pcircle++ = *psrc++; + + psrc = &(in->output1.outputCbcr.outFragments[2][0]); + for (i = 0; i < fcnt; i++) + *pdest++ = *psrc++; + + ctrl->viewPath.ackPending = FALSE; + ctrl->viewPath.currentFrame = ping; + ctrl->viewPath.whichOutputPath = 0; + ctrl->viewPath.yPath.fragIndex = 2; + ctrl->viewPath.cbcrPath.fragIndex = 2; + ctrl->viewPath.yPath.hwCurrentFlag = ping; + ctrl->viewPath.cbcrPath.hwCurrentFlag = ping; + + /* call to program the registers. */ + vfe_axi_output(in, &ctrl->viewPath, &ctrl->encPath, axioutpw); +} + +void vfe_camif_config(struct vfe_cmd_camif_config *in) +{ + struct vfe_camifcfg cmd; + memset(&cmd, 0, sizeof(cmd)); + + CDBG("camif.frame pixelsPerLine = %d\n", in->frame.pixelsPerLine); + CDBG("camif.frame linesPerFrame = %d\n", in->frame.linesPerFrame); + CDBG("camif.window firstpixel = %d\n", in->window.firstpixel); + CDBG("camif.window lastpixel = %d\n", in->window.lastpixel); + CDBG("camif.window firstline = %d\n", in->window.firstline); + CDBG("camif.window lastline = %d\n", in->window.lastline); + + /* determine if epoch interrupt needs to be enabled. */ + if ((in->epoch1.enable == TRUE) && + (in->epoch1.lineindex <= + in->frame.linesPerFrame)) + ctrl->vfeImaskLocal.camifEpoch1Irq = 1; + + if ((in->epoch2.enable == TRUE) && + (in->epoch2.lineindex <= + in->frame.linesPerFrame)) { + ctrl->vfeImaskLocal.camifEpoch2Irq = 1; + } + + /* save the content to program CAMIF_CONFIG separately. */ + ctrl->vfeCamifConfigLocal.camifCfgFromCmd = in->camifConfig; + + /* EFS_Config */ + cmd.efsEndOfLine = in->EFS.efsendofline; + cmd.efsStartOfLine = in->EFS.efsstartofline; + cmd.efsEndOfFrame = in->EFS.efsendofframe; + cmd.efsStartOfFrame = in->EFS.efsstartofframe; + + /* Frame Config */ + cmd.frameConfigPixelsPerLine = in->frame.pixelsPerLine; + cmd.frameConfigLinesPerFrame = in->frame.linesPerFrame; + + /* Window Width Config */ + cmd.windowWidthCfgLastPixel = in->window.lastpixel; + cmd.windowWidthCfgFirstPixel = in->window.firstpixel; + + /* Window Height Config */ + cmd.windowHeightCfglastLine = in->window.lastline; + cmd.windowHeightCfgfirstLine = in->window.firstline; + + /* Subsample 1 Config */ + cmd.subsample1CfgPixelSkip = in->subsample.pixelskipmask; + cmd.subsample1CfgLineSkip = in->subsample.lineskipmask; + + /* Subsample 2 Config */ + cmd.subsample2CfgFrameSkip = in->subsample.frameskip; + cmd.subsample2CfgFrameSkipMode = in->subsample.frameskipmode; + cmd.subsample2CfgPixelSkipWrap = in->subsample.pixelskipwrap; + + /* Epoch Interrupt */ + cmd.epoch1Line = in->epoch1.lineindex; + cmd.epoch2Line = in->epoch2.lineindex; + + vfe_prog_hw(ctrl->vfebase + CAMIF_EFS_CONFIG, + (uint32_t *)&cmd, sizeof(cmd)); +} + +void vfe_fov_crop_config(struct vfe_cmd_fov_crop_config *in) +{ + struct vfe_fov_crop_cfg cmd; + memset(&cmd, 0, sizeof(cmd)); + + ctrl->vfeModuleEnableLocal.cropEnable = in->enable; + + /* FOV Corp, Part 1 */ + cmd.lastPixel = in->lastPixel; + cmd.firstPixel = in->firstPixel; + + /* FOV Corp, Part 2 */ + cmd.lastLine = in->lastLine; + cmd.firstLine = in->firstLine; + + vfe_prog_hw(ctrl->vfebase + VFE_CROP_WIDTH_CFG, + (uint32_t *)&cmd, sizeof(cmd)); +} + +void vfe_get_hw_version(struct vfe_cmd_hw_version *out) +{ + uint32_t vfeHwVersionPacked; + struct vfe_hw_ver ver; + + vfeHwVersionPacked = readl(ctrl->vfebase + VFE_HW_VERSION); + + ver = *((struct vfe_hw_ver *)&vfeHwVersionPacked); + + out->coreVersion = ver.coreVersion; + out->minorVersion = ver.minorVersion; + out->majorVersion = ver.majorVersion; +} + +static void vfe_reset_internal_variables(void) +{ + unsigned long flags; + + /* local variables to program the hardware. */ + ctrl->vfeImaskPacked = 0; + ctrl->vfeImaskCompositePacked = 0; + + /* FALSE = disable, 1 = enable. */ + memset(&ctrl->vfeModuleEnableLocal, 0, + sizeof(ctrl->vfeModuleEnableLocal)); + + /* 0 = disable, 1 = enable */ + memset(&ctrl->vfeCamifConfigLocal, 0, + sizeof(ctrl->vfeCamifConfigLocal)); + /* 0 = disable, 1 = enable */ + memset(&ctrl->vfeImaskLocal, 0, sizeof(ctrl->vfeImaskLocal)); + memset(&ctrl->vfeStatsCmdLocal, 0, sizeof(ctrl->vfeStatsCmdLocal)); + memset(&ctrl->vfeBusConfigLocal, 0, sizeof(ctrl->vfeBusConfigLocal)); + memset(&ctrl->vfeBusPmConfigLocal, 0, + sizeof(ctrl->vfeBusPmConfigLocal)); + memset(&ctrl->vfeBusCmdLocal, 0, sizeof(ctrl->vfeBusCmdLocal)); + memset(&ctrl->vfeInterruptNameLocal, 0, + sizeof(ctrl->vfeInterruptNameLocal)); + memset(&ctrl->vfeDroppedFrameCounts, 0, + sizeof(ctrl->vfeDroppedFrameCounts)); + memset(&ctrl->vfeIrqThreadMsgLocal, 0, + sizeof(ctrl->vfeIrqThreadMsgLocal)); + + /* state control variables */ + ctrl->vfeStartAckPendingFlag = FALSE; + ctrl->vfeStopAckPending = FALSE; + ctrl->vfeIrqCompositeMaskLocal.ceDoneSel = 0; + ctrl->vfeIrqCompositeMaskLocal.encIrqComMask = + VFE_COMP_IRQ_BOTH_Y_CBCR; + ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask = + VFE_COMP_IRQ_BOTH_Y_CBCR; + + spin_lock_irqsave(&ctrl->state_lock, flags); + ctrl->vstate = VFE_STATE_IDLE; + spin_unlock_irqrestore(&ctrl->state_lock, flags); + + ctrl->axiOutputMode = VFE_AXI_LAST_OUTPUT_MODE_ENUM; + /* 0 for continuous mode, 1 for snapshot mode */ + ctrl->vfeOperationMode = VFE_START_OPERATION_MODE_CONTINUOUS; + ctrl->vfeSnapShotCount = 0; + ctrl->vfeStatsPingPongReloadFlag = FALSE; + /* this is unsigned 32 bit integer. */ + ctrl->vfeFrameId = 0; + ctrl->vfeFrameSkip.output1Pattern = 0xffffffff; + ctrl->vfeFrameSkip.output1Period = 31; + ctrl->vfeFrameSkip.output2Pattern = 0xffffffff; + ctrl->vfeFrameSkip.output2Period = 31; + ctrl->vfeFrameSkipPattern = 0xffffffff; + ctrl->vfeFrameSkipCount = 0; + ctrl->vfeFrameSkipPeriod = 31; + + memset((void *)&ctrl->encPath, 0, sizeof(ctrl->encPath)); + memset((void *)&ctrl->viewPath, 0, sizeof(ctrl->viewPath)); + + ctrl->encPath.whichOutputPath = 1; + ctrl->encPath.cbcrStatusBit = 5; + ctrl->viewPath.whichOutputPath = 0; + ctrl->viewPath.cbcrStatusBit = 7; + + ctrl->vfeTestGenStartFlag = FALSE; + + /* default to bank 0. */ + ctrl->vfeLaBankSel = 0; + + /* default to bank 0 for all channels. */ + memset(&ctrl->vfeGammaLutSel, 0, sizeof(ctrl->vfeGammaLutSel)); + + /* Stats control variables. */ + memset(&ctrl->afStatsControl, 0, sizeof(ctrl->afStatsControl)); + memset(&ctrl->awbStatsControl, 0, sizeof(ctrl->awbStatsControl)); + vfe_set_stats_pingpong_address(&ctrl->afStatsControl, + &ctrl->awbStatsControl); +} + +void vfe_reset(void) +{ + vfe_reset_internal_variables(); + + ctrl->vfeImaskLocal.resetAckIrq = TRUE; + ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal); + + /* disable all interrupts. */ + writel(VFE_DISABLE_ALL_IRQS, + ctrl->vfebase + VFE_IRQ_COMPOSITE_MASK); + + /* clear all pending interrupts*/ + writel(VFE_CLEAR_ALL_IRQS, + ctrl->vfebase + VFE_IRQ_CLEAR); + + /* enable reset_ack interrupt. */ + writel(ctrl->vfeImaskPacked, + ctrl->vfebase + VFE_IRQ_MASK); + + writel(VFE_RESET_UPON_RESET_CMD, + ctrl->vfebase + VFE_GLOBAL_RESET_CMD); +} diff --git a/trunk/drivers/staging/dream/camera/msm_vfe8x_proc.h b/trunk/drivers/staging/dream/camera/msm_vfe8x_proc.h new file mode 100644 index 000000000000..91828569a4d7 --- /dev/null +++ b/trunk/drivers/staging/dream/camera/msm_vfe8x_proc.h @@ -0,0 +1,1549 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ + +#ifndef __MSM_VFE8X_REG_H__ +#define __MSM_VFE8X_REG_H__ + +#include +#include +#include "msm_vfe8x.h" + +/* at start of camif, bit 1:0 = 0x01:enable + * image data capture at frame boundary. */ +#define CAMIF_COMMAND_START 0x00000005 + +/* bit 2= 0x1:clear the CAMIF_STATUS register + * value. */ +#define CAMIF_COMMAND_CLEAR 0x00000004 + +/* at stop of vfe pipeline, for now it is assumed + * that camif will stop at any time. Bit 1:0 = 0x10: + * disable image data capture immediately. */ +#define CAMIF_COMMAND_STOP_IMMEDIATELY 0x00000002 + +/* at stop of vfe pipeline, for now it is assumed + * that camif will stop at any time. Bit 1:0 = 0x00: + * disable image data capture at frame boundary */ +#define CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY 0x00000000 + +/* to halt axi bridge */ +#define AXI_HALT 0x00000001 + +/* clear the halt bit. */ +#define AXI_HALT_CLEAR 0x00000000 + +/* reset the pipeline when stop command is issued. + * (without reset the register.) bit 26-31 = 0, + * domain reset, bit 0-9 = 1 for module reset, except + * register module. */ +#define VFE_RESET_UPON_STOP_CMD 0x000003ef + +/* reset the pipeline when reset command. + * bit 26-31 = 0, domain reset, bit 0-9 = 1 for module reset. */ +#define VFE_RESET_UPON_RESET_CMD 0x000003ff + +/* bit 5 is for axi status idle or busy. + * 1 = halted, 0 = busy */ +#define AXI_STATUS_BUSY_MASK 0x00000020 + +/* bit 0 & bit 1 = 1, both y and cbcr irqs need to be present + * for frame done interrupt */ +#define VFE_COMP_IRQ_BOTH_Y_CBCR 3 + +/* bit 1 = 1, only cbcr irq triggers frame done interrupt */ +#define VFE_COMP_IRQ_CBCR_ONLY 2 + +/* bit 0 = 1, only y irq triggers frame done interrupt */ +#define VFE_COMP_IRQ_Y_ONLY 1 + +/* bit 0 = 1, PM go; bit1 = 1, PM stop */ +#define VFE_PERFORMANCE_MONITOR_GO 0x00000001 +#define VFE_PERFORMANCE_MONITOR_STOP 0x00000002 + +/* bit 0 = 1, test gen go; bit1 = 1, test gen stop */ +#define VFE_TEST_GEN_GO 0x00000001 +#define VFE_TEST_GEN_STOP 0x00000002 + +/* the chroma is assumed to be interpolated between + * the luma samples. JPEG 4:2:2 */ +#define VFE_CHROMA_UPSAMPLE_INTERPOLATED 0 + +/* constants for irq registers */ +#define VFE_DISABLE_ALL_IRQS 0 +/* bit =1 is to clear the corresponding bit in VFE_IRQ_STATUS. */ +#define VFE_CLEAR_ALL_IRQS 0xffffffff +/* imask for while waiting for stop ack, driver has already + * requested stop, waiting for reset irq, + * bit 29,28,27,26 for async timer, bit 9 for reset */ +#define VFE_IMASK_WHILE_STOPPING 0x3c000200 + +/* when normal case, don't want to block error status. + * bit 0,6,20,21,22,30,31 */ +#define VFE_IMASK_ERROR_ONLY 0xC0700041 +#define VFE_REG_UPDATE_TRIGGER 1 +#define VFE_PM_BUF_MAX_CNT_MASK 0xFF +#define VFE_DMI_CFG_DEFAULT 0x00000100 +#define LENS_ROLL_OFF_DELTA_TABLE_OFFSET 32 +#define VFE_AF_PINGPONG_STATUS_BIT 0x100 +#define VFE_AWB_PINGPONG_STATUS_BIT 0x200 + +/* VFE I/O registers */ +enum { + VFE_HW_VERSION = 0x00000000, + VFE_GLOBAL_RESET_CMD = 0x00000004, + VFE_MODULE_RESET = 0x00000008, + VFE_CGC_OVERRIDE = 0x0000000C, + VFE_MODULE_CFG = 0x00000010, + VFE_CFG = 0x00000014, + VFE_IRQ_MASK = 0x00000018, + VFE_IRQ_CLEAR = 0x0000001C, +VFE_IRQ_STATUS = 0x00000020, +VFE_IRQ_COMPOSITE_MASK = 0x00000024, +VFE_BUS_CMD = 0x00000028, +VFE_BUS_CFG = 0x0000002C, +VFE_BUS_ENC_Y_WR_PING_ADDR = 0x00000030, +VFE_BUS_ENC_Y_WR_PONG_ADDR = 0x00000034, +VFE_BUS_ENC_Y_WR_IMAGE_SIZE = 0x00000038, +VFE_BUS_ENC_Y_WR_BUFFER_CFG = 0x0000003C, +VFE_BUS_ENC_CBCR_WR_PING_ADDR = 0x00000040, +VFE_BUS_ENC_CBCR_WR_PONG_ADDR = 0x00000044, +VFE_BUS_ENC_CBCR_WR_IMAGE_SIZE = 0x00000048, +VFE_BUS_ENC_CBCR_WR_BUFFER_CFG = 0x0000004C, +VFE_BUS_VIEW_Y_WR_PING_ADDR = 0x00000050, +VFE_BUS_VIEW_Y_WR_PONG_ADDR = 0x00000054, +VFE_BUS_VIEW_Y_WR_IMAGE_SIZE = 0x00000058, +VFE_BUS_VIEW_Y_WR_BUFFER_CFG = 0x0000005C, +VFE_BUS_VIEW_CBCR_WR_PING_ADDR = 0x00000060, +VFE_BUS_VIEW_CBCR_WR_PONG_ADDR = 0x00000064, +VFE_BUS_VIEW_CBCR_WR_IMAGE_SIZE = 0x00000068, +VFE_BUS_VIEW_CBCR_WR_BUFFER_CFG = 0x0000006C, +VFE_BUS_STATS_AF_WR_PING_ADDR = 0x00000070, +VFE_BUS_STATS_AF_WR_PONG_ADDR = 0x00000074, +VFE_BUS_STATS_AWB_WR_PING_ADDR = 0x00000078, +VFE_BUS_STATS_AWB_WR_PONG_ADDR = 0x0000007C, +VFE_BUS_STATS_HIST_WR_PING_ADDR = 0x00000080, +VFE_BUS_STATS_HIST_WR_PONG_ADDR = 0x00000084, +VFE_BUS_STATS_WR_PRIORITY = 0x00000088, +VFE_BUS_STRIPE_RD_ADDR_0 = 0x0000008C, +VFE_BUS_STRIPE_RD_ADDR_1 = 0x00000090, +VFE_BUS_STRIPE_RD_ADDR_2 = 0x00000094, +VFE_BUS_STRIPE_RD_ADDR_3 = 0x00000098, +VFE_BUS_STRIPE_RD_VSIZE = 0x0000009C, +VFE_BUS_STRIPE_RD_HSIZE = 0x000000A0, +VFE_BUS_STRIPE_RD_BUFFER_CFG = 0x000000A4, +VFE_BUS_STRIPE_RD_UNPACK_CFG = 0x000000A8, +VFE_BUS_STRIPE_RD_UNPACK = 0x000000AC, +VFE_BUS_STRIPE_RD_PAD_SIZE = 0x000000B0, +VFE_BUS_STRIPE_RD_PAD_L_UNPACK = 0x000000B4, +VFE_BUS_STRIPE_RD_PAD_R_UNPACK = 0x000000B8, +VFE_BUS_STRIPE_RD_PAD_TB_UNPACK = 0x000000BC, +VFE_BUS_PINGPONG_IRQ_EN = 0x000000C0, +VFE_BUS_PINGPONG_STATUS = 0x000000C4, +VFE_BUS_PM_CMD = 0x000000C8, +VFE_BUS_PM_CFG = 0x000000CC, +VFE_BUS_ENC_Y_WR_PM_STATS_0 = 0x000000D0, +VFE_BUS_ENC_Y_WR_PM_STATS_1 = 0x000000D4, +VFE_BUS_ENC_CBCR_WR_PM_STATS_0 = 0x000000D8, +VFE_BUS_ENC_CBCR_WR_PM_STATS_1 = 0x000000DC, +VFE_BUS_VIEW_Y_WR_PM_STATS_0 = 0x000000E0, +VFE_BUS_VIEW_Y_WR_PM_STATS_1 = 0x000000E4, +VFE_BUS_VIEW_CBCR_WR_PM_STATS_0 = 0x000000E8, +VFE_BUS_VIEW_CBCR_WR_PM_STATS_1 = 0x000000EC, +VFE_BUS_MISR_CFG = 0x000000F4, +VFE_BUS_MISR_MAST_CFG_0 = 0x000000F8, +VFE_BUS_MISR_MAST_CFG_1 = 0x000000FC, +VFE_BUS_MISR_RD_VAL = 0x00000100, +VFE_AXI_CMD = 0x00000104, +VFE_AXI_CFG = 0x00000108, +VFE_AXI_STATUS = 0x0000010C, +CAMIF_COMMAND = 0x00000110, +CAMIF_CONFIG = 0x00000114, +CAMIF_EFS_CONFIG = 0x00000118, +CAMIF_FRAME_CONFIG = 0x0000011C, +CAMIF_WINDOW_WIDTH_CONFIG = 0x00000120, +CAMIF_WINDOW_HEIGHT_CONFIG = 0x00000124, +CAMIF_SUBSAMPLE1_CONFIG = 0x00000128, +CAMIF_SUBSAMPLE2_CONFIG = 0x0000012C, +CAMIF_EPOCH_IRQ = 0x00000130, +CAMIF_STATUS = 0x00000134, +CAMIF_MISR = 0x00000138, +VFE_SYNC_TIMER_CMD = 0x0000013C, +VFE_SYNC_TIMER0_LINE_START = 0x00000140, +VFE_SYNC_TIMER0_PIXEL_START = 0x00000144, +VFE_SYNC_TIMER0_PIXEL_DURATION = 0x00000148, +VFE_SYNC_TIMER1_LINE_START = 0x0000014C, +VFE_SYNC_TIMER1_PIXEL_START = 0x00000150, +VFE_SYNC_TIMER1_PIXEL_DURATION = 0x00000154, +VFE_SYNC_TIMER2_LINE_START = 0x00000158, +VFE_SYNC_TIMER2_PIXEL_START = 0x0000015C, +VFE_SYNC_TIMER2_PIXEL_DURATION = 0x00000160, +VFE_SYNC_TIMER_POLARITY = 0x00000164, +VFE_ASYNC_TIMER_CMD = 0x00000168, +VFE_ASYNC_TIMER0_CFG_0 = 0x0000016C, +VFE_ASYNC_TIMER0_CFG_1 = 0x00000170, +VFE_ASYNC_TIMER1_CFG_0 = 0x00000174, +VFE_ASYNC_TIMER1_CFG_1 = 0x00000178, +VFE_ASYNC_TIMER2_CFG_0 = 0x0000017C, +VFE_ASYNC_TIMER2_CFG_1 = 0x00000180, +VFE_ASYNC_TIMER3_CFG_0 = 0x00000184, +VFE_ASYNC_TIMER3_CFG_1 = 0x00000188, +VFE_TIMER_SEL = 0x0000018C, +VFE_REG_UPDATE_CMD = 0x00000190, +VFE_BLACK_EVEN_EVEN_VALUE = 0x00000194, +VFE_BLACK_EVEN_ODD_VALUE = 0x00000198, +VFE_BLACK_ODD_EVEN_VALUE = 0x0000019C, +VFE_BLACK_ODD_ODD_VALUE = 0x000001A0, +VFE_ROLLOFF_CFG_0 = 0x000001A4, +VFE_ROLLOFF_CFG_1 = 0x000001A8, +VFE_ROLLOFF_CFG_2 = 0x000001AC, +VFE_DEMUX_CFG = 0x000001B0, +VFE_DEMUX_GAIN_0 = 0x000001B4, +VFE_DEMUX_GAIN_1 = 0x000001B8, +VFE_DEMUX_EVEN_CFG = 0x000001BC, +VFE_DEMUX_ODD_CFG = 0x000001C0, +VFE_DEMOSAIC_CFG = 0x000001C4, +VFE_DEMOSAIC_ABF_CFG_0 = 0x000001C8, +VFE_DEMOSAIC_ABF_CFG_1 = 0x000001CC, +VFE_DEMOSAIC_BPC_CFG_0 = 0x000001D0, +VFE_DEMOSAIC_BPC_CFG_1 = 0x000001D4, +VFE_DEMOSAIC_STATUS = 0x000001D8, +VFE_CHROMA_UPSAMPLE_CFG = 0x000001DC, +VFE_CROP_WIDTH_CFG = 0x000001E0, +VFE_CROP_HEIGHT_CFG = 0x000001E4, +VFE_COLOR_CORRECT_COEFF_0 = 0x000001E8, +VFE_COLOR_CORRECT_COEFF_1 = 0x000001EC, +VFE_COLOR_CORRECT_COEFF_2 = 0x000001F0, +VFE_COLOR_CORRECT_COEFF_3 = 0x000001F4, +VFE_COLOR_CORRECT_COEFF_4 = 0x000001F8, +VFE_COLOR_CORRECT_COEFF_5 = 0x000001FC, +VFE_COLOR_CORRECT_COEFF_6 = 0x00000200, +VFE_COLOR_CORRECT_COEFF_7 = 0x00000204, +VFE_COLOR_CORRECT_COEFF_8 = 0x00000208, +VFE_COLOR_CORRECT_OFFSET_0 = 0x0000020C, +VFE_COLOR_CORRECT_OFFSET_1 = 0x00000210, +VFE_COLOR_CORRECT_OFFSET_2 = 0x00000214, +VFE_COLOR_CORRECT_COEFF_Q = 0x00000218, +VFE_LA_CFG = 0x0000021C, +VFE_LUT_BANK_SEL = 0x00000220, +VFE_CHROMA_ENHAN_A = 0x00000224, +VFE_CHROMA_ENHAN_B = 0x00000228, +VFE_CHROMA_ENHAN_C = 0x0000022C, +VFE_CHROMA_ENHAN_D = 0x00000230, +VFE_CHROMA_ENHAN_K = 0x00000234, +VFE_COLOR_CONVERT_COEFF_0 = 0x00000238, +VFE_COLOR_CONVERT_COEFF_1 = 0x0000023C, +VFE_COLOR_CONVERT_COEFF_2 = 0x00000240, +VFE_COLOR_CONVERT_OFFSET = 0x00000244, +VFE_ASF_CFG = 0x00000248, +VFE_ASF_SHARP_CFG_0 = 0x0000024C, +VFE_ASF_SHARP_CFG_1 = 0x00000250, +VFE_ASF_SHARP_COEFF_0 = 0x00000254, +VFE_ASF_SHARP_COEFF_1 = 0x00000258, +VFE_ASF_SHARP_COEFF_2 = 0x0000025C, +VFE_ASF_SHARP_COEFF_3 = 0x00000260, +VFE_ASF_MAX_EDGE = 0x00000264, +VFE_ASF_CROP_WIDTH_CFG = 0x00000268, +VFE_ASF_CROP_HEIGHT_CFG = 0x0000026C, +VFE_SCALE_CFG = 0x00000270, +VFE_SCALE_H_IMAGE_SIZE_CFG = 0x00000274, +VFE_SCALE_H_PHASE_CFG = 0x00000278, +VFE_SCALE_H_STRIPE_CFG = 0x0000027C, +VFE_SCALE_V_IMAGE_SIZE_CFG = 0x00000280, +VFE_SCALE_V_PHASE_CFG = 0x00000284, +VFE_SCALE_V_STRIPE_CFG = 0x00000288, +VFE_SCALE_Y_CFG = 0x0000028C, +VFE_SCALE_Y_H_IMAGE_SIZE_CFG = 0x00000290, +VFE_SCALE_Y_H_PHASE_CFG = 0x00000294, +VFE_SCALE_Y_V_IMAGE_SIZE_CFG = 0x00000298, +VFE_SCALE_Y_V_PHASE_CFG = 0x0000029C, +VFE_SCALE_CBCR_CFG = 0x000002A0, +VFE_SCALE_CBCR_H_IMAGE_SIZE_CFG = 0x000002A4, +VFE_SCALE_CBCR_H_PHASE_CFG = 0x000002A8, +VFE_SCALE_CBCR_V_IMAGE_SIZE_CFG = 0x000002AC, +VFE_SCALE_CBCR_V_PHASE_CFG = 0x000002B0, +VFE_WB_CFG = 0x000002B4, +VFE_CHROMA_SUPPRESS_CFG_0 = 0x000002B8, +VFE_CHROMA_SUPPRESS_CFG_1 = 0x000002BC, +VFE_CHROMA_SUBSAMPLE_CFG = 0x000002C0, +VFE_CHROMA_SUB_CROP_WIDTH_CFG = 0x000002C4, +VFE_CHROMA_SUB_CROP_HEIGHT_CFG = 0x000002C8, +VFE_FRAMEDROP_ENC_Y_CFG = 0x000002CC, +VFE_FRAMEDROP_ENC_CBCR_CFG = 0x000002D0, +VFE_FRAMEDROP_ENC_Y_PATTERN = 0x000002D4, +VFE_FRAMEDROP_ENC_CBCR_PATTERN = 0x000002D8, +VFE_FRAMEDROP_VIEW_Y_CFG = 0x000002DC, +VFE_FRAMEDROP_VIEW_CBCR_CFG = 0x000002E0, +VFE_FRAMEDROP_VIEW_Y_PATTERN = 0x000002E4, +VFE_FRAMEDROP_VIEW_CBCR_PATTERN = 0x000002E8, +VFE_CLAMP_MAX_CFG = 0x000002EC, +VFE_CLAMP_MIN_CFG = 0x000002F0, +VFE_STATS_CMD = 0x000002F4, +VFE_STATS_AF_CFG = 0x000002F8, +VFE_STATS_AF_DIM = 0x000002FC, +VFE_STATS_AF_GRID_0 = 0x00000300, +VFE_STATS_AF_GRID_1 = 0x00000304, +VFE_STATS_AF_GRID_2 = 0x00000308, +VFE_STATS_AF_GRID_3 = 0x0000030C, +VFE_STATS_AF_HEADER = 0x00000310, +VFE_STATS_AF_COEF0 = 0x00000314, +VFE_STATS_AF_COEF1 = 0x00000318, +VFE_STATS_AWBAE_CFG = 0x0000031C, +VFE_STATS_AXW_HEADER = 0x00000320, +VFE_STATS_AWB_MCFG = 0x00000324, +VFE_STATS_AWB_CCFG1 = 0x00000328, +VFE_STATS_AWB_CCFG2 = 0x0000032C, +VFE_STATS_HIST_HEADER = 0x00000330, +VFE_STATS_HIST_INNER_OFFSET = 0x00000334, +VFE_STATS_HIST_INNER_DIM = 0x00000338, +VFE_STATS_FRAME_SIZE = 0x0000033C, +VFE_DMI_CFG = 0x00000340, +VFE_DMI_ADDR = 0x00000344, +VFE_DMI_DATA_HI = 0x00000348, +VFE_DMI_DATA_LO = 0x0000034C, +VFE_DMI_RAM_AUTO_LOAD_CMD = 0x00000350, +VFE_DMI_RAM_AUTO_LOAD_STATUS = 0x00000354, +VFE_DMI_RAM_AUTO_LOAD_CFG = 0x00000358, +VFE_DMI_RAM_AUTO_LOAD_SEED = 0x0000035C, +VFE_TESTBUS_SEL = 0x00000360, +VFE_TESTGEN_CFG = 0x00000364, +VFE_SW_TESTGEN_CMD = 0x00000368, +VFE_HW_TESTGEN_CMD = 0x0000036C, +VFE_HW_TESTGEN_CFG = 0x00000370, +VFE_HW_TESTGEN_IMAGE_CFG = 0x00000374, +VFE_HW_TESTGEN_SOF_OFFSET_CFG = 0x00000378, +VFE_HW_TESTGEN_EOF_NOFFSET_CFG = 0x0000037C, +VFE_HW_TESTGEN_SOL_OFFSET_CFG = 0x00000380, +VFE_HW_TESTGEN_EOL_NOFFSET_CFG = 0x00000384, +VFE_HW_TESTGEN_HBI_CFG = 0x00000388, +VFE_HW_TESTGEN_VBL_CFG = 0x0000038C, +VFE_HW_TESTGEN_SOF_DUMMY_LINE_CFG2 = 0x00000390, +VFE_HW_TESTGEN_EOF_DUMMY_LINE_CFG2 = 0x00000394, +VFE_HW_TESTGEN_COLOR_BARS_CFG = 0x00000398, +VFE_HW_TESTGEN_RANDOM_CFG = 0x0000039C, +VFE_SPARE = 0x000003A0, +}; + +#define ping 0x0 +#define pong 0x1 + +struct vfe_bus_cfg_data { + boolean stripeRdPathEn; + boolean encYWrPathEn; + boolean encCbcrWrPathEn; + boolean viewYWrPathEn; + boolean viewCbcrWrPathEn; + enum VFE_RAW_PIXEL_DATA_SIZE rawPixelDataSize; + enum VFE_RAW_WR_PATH_SEL rawWritePathSelect; +}; + +struct vfe_camif_cfg_data { + boolean camif2OutputEnable; + boolean camif2BusEnable; + struct vfe_cmds_camif_cfg camifCfgFromCmd; +}; + +struct vfe_irq_composite_mask_config { + uint8_t encIrqComMask; + uint8_t viewIrqComMask; + uint8_t ceDoneSel; +}; + +/* define a structure for each output path.*/ +struct vfe_output_path { + uint32_t addressBuffer[8]; + uint16_t fragIndex; + boolean hwCurrentFlag; + uint8_t *hwRegPingAddress; + uint8_t *hwRegPongAddress; +}; + +struct vfe_output_path_combo { + boolean whichOutputPath; + boolean pathEnabled; + boolean multiFrag; + uint8_t fragCount; + boolean ackPending; + uint8_t currentFrame; + uint32_t nextFrameAddrBuf[8]; + struct vfe_output_path yPath; + struct vfe_output_path cbcrPath; + uint8_t snapshotPendingCount; + boolean pmEnabled; + uint8_t cbcrStatusBit; +}; + +struct vfe_stats_control { + boolean ackPending; + uint32_t addressBuffer[2]; + uint32_t nextFrameAddrBuf; + boolean pingPongStatus; + uint8_t *hwRegPingAddress; + uint8_t *hwRegPongAddress; + uint32_t droppedStatsFrameCount; + uint32_t bufToRender; +}; + +struct vfe_gamma_lut_sel { + boolean ch0BankSelect; + boolean ch1BankSelect; + boolean ch2BankSelect; +}; + +struct vfe_interrupt_mask { + boolean camifErrorIrq; + boolean camifSofIrq; + boolean camifEolIrq; + boolean camifEofIrq; + boolean camifEpoch1Irq; + boolean camifEpoch2Irq; + boolean camifOverflowIrq; + boolean ceIrq; + boolean regUpdateIrq; + boolean resetAckIrq; + boolean encYPingpongIrq; + boolean encCbcrPingpongIrq; + boolean viewYPingpongIrq; + boolean viewCbcrPingpongIrq; + boolean rdPingpongIrq; + boolean afPingpongIrq; + boolean awbPingpongIrq; + boolean histPingpongIrq; + boolean encIrq; + boolean viewIrq; + boolean busOverflowIrq; + boolean afOverflowIrq; + boolean awbOverflowIrq; + boolean syncTimer0Irq; + boolean syncTimer1Irq; + boolean syncTimer2Irq; + boolean asyncTimer0Irq; + boolean asyncTimer1Irq; + boolean asyncTimer2Irq; + boolean asyncTimer3Irq; + boolean axiErrorIrq; + boolean violationIrq; +}; + +enum vfe_interrupt_name { + CAMIF_ERROR_IRQ, + CAMIF_SOF_IRQ, + CAMIF_EOL_IRQ, + CAMIF_EOF_IRQ, + CAMIF_EPOCH1_IRQ, + CAMIF_EPOCH2_IRQ, + CAMIF_OVERFLOW_IRQ, + CE_IRQ, + REG_UPDATE_IRQ, + RESET_ACK_IRQ, + ENC_Y_PINGPONG_IRQ, + ENC_CBCR_PINGPONG_IRQ, + VIEW_Y_PINGPONG_IRQ, + VIEW_CBCR_PINGPONG_IRQ, + RD_PINGPONG_IRQ, + AF_PINGPONG_IRQ, + AWB_PINGPONG_IRQ, + HIST_PINGPONG_IRQ, + ENC_IRQ, + VIEW_IRQ, + BUS_OVERFLOW_IRQ, + AF_OVERFLOW_IRQ, + AWB_OVERFLOW_IRQ, + SYNC_TIMER0_IRQ, + SYNC_TIMER1_IRQ, + SYNC_TIMER2_IRQ, + ASYNC_TIMER0_IRQ, + ASYNC_TIMER1_IRQ, + ASYNC_TIMER2_IRQ, + ASYNC_TIMER3_IRQ, + AXI_ERROR_IRQ, + VIOLATION_IRQ +}; + +enum VFE_DMI_RAM_SEL { + NO_MEM_SELECTED = 0, + ROLLOFF_RAM = 0x1, + RGBLUT_RAM_CH0_BANK0 = 0x2, + RGBLUT_RAM_CH0_BANK1 = 0x3, + RGBLUT_RAM_CH1_BANK0 = 0x4, + RGBLUT_RAM_CH1_BANK1 = 0x5, + RGBLUT_RAM_CH2_BANK0 = 0x6, + RGBLUT_RAM_CH2_BANK1 = 0x7, + STATS_HIST_CB_EVEN_RAM = 0x8, + STATS_HIST_CB_ODD_RAM = 0x9, + STATS_HIST_CR_EVEN_RAM = 0xa, + STATS_HIST_CR_ODD_RAM = 0xb, + RGBLUT_CHX_BANK0 = 0xc, + RGBLUT_CHX_BANK1 = 0xd, + LUMA_ADAPT_LUT_RAM_BANK0 = 0xe, + LUMA_ADAPT_LUT_RAM_BANK1 = 0xf +}; + +struct vfe_module_enable { + boolean blackLevelCorrectionEnable; + boolean lensRollOffEnable; + boolean demuxEnable; + boolean chromaUpsampleEnable; + boolean demosaicEnable; + boolean statsEnable; + boolean cropEnable; + boolean mainScalerEnable; + boolean whiteBalanceEnable; + boolean colorCorrectionEnable; + boolean yHistEnable; + boolean skinToneEnable; + boolean lumaAdaptationEnable; + boolean rgbLUTEnable; + boolean chromaEnhanEnable; + boolean asfEnable; + boolean chromaSuppressionEnable; + boolean chromaSubsampleEnable; + boolean scaler2YEnable; + boolean scaler2CbcrEnable; +}; + +struct vfe_bus_cmd_data { + boolean stripeReload; + boolean busPingpongReload; + boolean statsPingpongReload; +}; + +struct vfe_stats_cmd_data { + boolean autoFocusEnable; + boolean axwEnable; + boolean histEnable; + boolean clearHistEnable; + boolean histAutoClearEnable; + boolean colorConversionEnable; +}; + +struct vfe_hw_ver { + uint32_t minorVersion:8; + uint32_t majorVersion:8; + uint32_t coreVersion:4; + uint32_t /* reserved */ : 12; +} __attribute__((packed, aligned(4))); + +struct vfe_cfg { + uint32_t pixelPattern:3; + uint32_t /* reserved */ : 13; + uint32_t inputSource:2; + uint32_t /* reserved */ : 14; +} __attribute__((packed, aligned(4))); + +struct vfe_buscmd { + uint32_t stripeReload:1; + uint32_t /* reserved */ : 3; + uint32_t busPingpongReload:1; + uint32_t statsPingpongReload:1; + uint32_t /* reserved */ : 26; +} __attribute__((packed, aligned(4))); + +struct VFE_Irq_Composite_MaskType { + uint32_t encIrqComMaskBits:2; + uint32_t viewIrqComMaskBits:2; + uint32_t ceDoneSelBits:5; + uint32_t /* reserved */ : 23; +} __attribute__((packed, aligned(4))); + +struct vfe_mod_enable { + uint32_t blackLevelCorrectionEnable:1; + uint32_t lensRollOffEnable:1; + uint32_t demuxEnable:1; + uint32_t chromaUpsampleEnable:1; + uint32_t demosaicEnable:1; + uint32_t statsEnable:1; + uint32_t cropEnable:1; + uint32_t mainScalerEnable:1; + uint32_t whiteBalanceEnable:1; + uint32_t colorCorrectionEnable:1; + uint32_t yHistEnable:1; + uint32_t skinToneEnable:1; + uint32_t lumaAdaptationEnable:1; + uint32_t rgbLUTEnable:1; + uint32_t chromaEnhanEnable:1; + uint32_t asfEnable:1; + uint32_t chromaSuppressionEnable:1; + uint32_t chromaSubsampleEnable:1; + uint32_t scaler2YEnable:1; + uint32_t scaler2CbcrEnable:1; + uint32_t /* reserved */ : 14; +} __attribute__((packed, aligned(4))); + +struct vfe_irqenable { + uint32_t camifErrorIrq:1; + uint32_t camifSofIrq:1; + uint32_t camifEolIrq:1; + uint32_t camifEofIrq:1; + uint32_t camifEpoch1Irq:1; + uint32_t camifEpoch2Irq:1; + uint32_t camifOverflowIrq:1; + uint32_t ceIrq:1; + uint32_t regUpdateIrq:1; + uint32_t resetAckIrq:1; + uint32_t encYPingpongIrq:1; + uint32_t encCbcrPingpongIrq:1; + uint32_t viewYPingpongIrq:1; + uint32_t viewCbcrPingpongIrq:1; + uint32_t rdPingpongIrq:1; + uint32_t afPingpongIrq:1; + uint32_t awbPingpongIrq:1; + uint32_t histPingpongIrq:1; + uint32_t encIrq:1; + uint32_t viewIrq:1; + uint32_t busOverflowIrq:1; + uint32_t afOverflowIrq:1; + uint32_t awbOverflowIrq:1; + uint32_t syncTimer0Irq:1; + uint32_t syncTimer1Irq:1; + uint32_t syncTimer2Irq:1; + uint32_t asyncTimer0Irq:1; + uint32_t asyncTimer1Irq:1; + uint32_t asyncTimer2Irq:1; + uint32_t asyncTimer3Irq:1; + uint32_t axiErrorIrq:1; + uint32_t violationIrq:1; +} __attribute__((packed, aligned(4))); + +struct vfe_upsample_cfg { + uint32_t chromaCositingForYCbCrInputs:1; + uint32_t /* reserved */ : 31; +} __attribute__((packed, aligned(4))); + +struct VFE_CAMIFConfigType { + /* CAMIF Config */ + uint32_t /* reserved */ : 1; + uint32_t VSyncEdge:1; + uint32_t HSyncEdge:1; + uint32_t syncMode:2; + uint32_t vfeSubsampleEnable:1; + uint32_t /* reserved */ : 1; + uint32_t busSubsampleEnable:1; + uint32_t camif2vfeEnable:1; + uint32_t /* reserved */ : 1; + uint32_t camif2busEnable:1; + uint32_t irqSubsampleEnable:1; + uint32_t binningEnable:1; + uint32_t /* reserved */ : 18; + uint32_t misrEnable:1; +} __attribute__((packed, aligned(4))); + +struct vfe_camifcfg { + /* EFS_Config */ + uint32_t efsEndOfLine:8; + uint32_t efsStartOfLine:8; + uint32_t efsEndOfFrame:8; + uint32_t efsStartOfFrame:8; + /* Frame Config */ + uint32_t frameConfigPixelsPerLine:14; + uint32_t /* reserved */ : 2; + uint32_t frameConfigLinesPerFrame:14; + uint32_t /* reserved */ : 2; + /* Window Width Config */ + uint32_t windowWidthCfgLastPixel:14; + uint32_t /* reserved */ : 2; + uint32_t windowWidthCfgFirstPixel:14; + uint32_t /* reserved */ : 2; + /* Window Height Config */ + uint32_t windowHeightCfglastLine:14; + uint32_t /* reserved */ : 2; + uint32_t windowHeightCfgfirstLine:14; + uint32_t /* reserved */ : 2; + /* Subsample 1 Config */ + uint32_t subsample1CfgPixelSkip:16; + uint32_t subsample1CfgLineSkip:16; + /* Subsample 2 Config */ + uint32_t subsample2CfgFrameSkip:4; + uint32_t subsample2CfgFrameSkipMode:1; + uint32_t subsample2CfgPixelSkipWrap:1; + uint32_t /* reserved */ : 26; + /* Epoch Interrupt */ + uint32_t epoch1Line:14; + uint32_t /* reserved */ : 2; + uint32_t epoch2Line:14; + uint32_t /* reserved */ : 2; +} __attribute__((packed, aligned(4))); + +struct vfe_camifframe_update { + uint32_t pixelsPerLine:14; + uint32_t /* reserved */ : 2; + uint32_t linesPerFrame:14; + uint32_t /* reserved */ : 2; +} __attribute__((packed, aligned(4))); + +struct vfe_axi_bus_cfg { + uint32_t stripeRdPathEn:1; + uint32_t /* reserved */ : 3; + uint32_t encYWrPathEn:1; + uint32_t encCbcrWrPathEn:1; + uint32_t viewYWrPathEn:1; + uint32_t viewCbcrWrPathEn:1; + uint32_t rawPixelDataSize:2; + uint32_t rawWritePathSelect:2; + uint32_t /* reserved */ : 20; +} __attribute__((packed, aligned(4))); + +struct vfe_axi_out_cfg { + uint32_t out2YPingAddr:32; + uint32_t out2YPongAddr:32; + uint32_t out2YImageHeight:12; + uint32_t /* reserved */ : 4; + uint32_t out2YImageWidthin64bit:10; + uint32_t /* reserved */ : 6; + uint32_t out2YBurstLength:2; + uint32_t /* reserved */ : 2; + uint32_t out2YNumRows:12; + uint32_t out2YRowIncrementIn64bit:12; + uint32_t /* reserved */ : 4; + uint32_t out2CbcrPingAddr:32; + uint32_t out2CbcrPongAddr:32; + uint32_t out2CbcrImageHeight:12; + uint32_t /* reserved */ : 4; + uint32_t out2CbcrImageWidthIn64bit:10; + uint32_t /* reserved */ : 6; + uint32_t out2CbcrBurstLength:2; + uint32_t /* reserved */ : 2; + uint32_t out2CbcrNumRows:12; + uint32_t out2CbcrRowIncrementIn64bit:12; + uint32_t /* reserved */ : 4; + uint32_t out1YPingAddr:32; + uint32_t out1YPongAddr:32; + uint32_t out1YImageHeight:12; + uint32_t /* reserved */ : 4; + uint32_t out1YImageWidthin64bit:10; + uint32_t /* reserved */ : 6; + uint32_t out1YBurstLength:2; + uint32_t /* reserved */ : 2; + uint32_t out1YNumRows:12; + uint32_t out1YRowIncrementIn64bit:12; + uint32_t /* reserved */ : 4; + uint32_t out1CbcrPingAddr:32; + uint32_t out1CbcrPongAddr:32; + uint32_t out1CbcrImageHeight:12; + uint32_t /* reserved */ : 4; + uint32_t out1CbcrImageWidthIn64bit:10; + uint32_t /* reserved */ : 6; + uint32_t out1CbcrBurstLength:2; + uint32_t /* reserved */ : 2; + uint32_t out1CbcrNumRows:12; + uint32_t out1CbcrRowIncrementIn64bit:12; + uint32_t /* reserved */ : 4; +} __attribute__((packed, aligned(4))); + +struct vfe_output_clamp_cfg { + /* Output Clamp Maximums */ + uint32_t yChanMax:8; + uint32_t cbChanMax:8; + uint32_t crChanMax:8; + uint32_t /* reserved */ : 8; + /* Output Clamp Minimums */ + uint32_t yChanMin:8; + uint32_t cbChanMin:8; + uint32_t crChanMin:8; + uint32_t /* reserved */ : 8; +} __attribute__((packed, aligned(4))); + +struct vfe_fov_crop_cfg { + uint32_t lastPixel:12; + uint32_t /* reserved */ : 4; + uint32_t firstPixel:12; + uint32_t /* reserved */ : 4; + + /* FOV Corp, Part 2 */ + uint32_t lastLine:12; + uint32_t /* reserved */ : 4; + uint32_t firstLine:12; + uint32_t /* reserved */ : 4; +} __attribute__((packed, aligned(4))); + +struct VFE_FRAME_SKIP_UpdateCmdType { + uint32_t yPattern:32; + uint32_t cbcrPattern:32; +} __attribute__((packed, aligned(4))); + +struct vfe_frame_skip_cfg { + /* Frame Drop Enc (output2) */ + uint32_t output2YPeriod:5; + uint32_t /* reserved */ : 27; + uint32_t output2CbCrPeriod:5; + uint32_t /* reserved */ : 27; + uint32_t output2YPattern:32; + uint32_t output2CbCrPattern:32; + /* Frame Drop View (output1) */ + uint32_t output1YPeriod:5; + uint32_t /* reserved */ : 27; + uint32_t output1CbCrPeriod:5; + uint32_t /* reserved */ : 27; + uint32_t output1YPattern:32; + uint32_t output1CbCrPattern:32; +} __attribute__((packed, aligned(4))); + +struct vfe_main_scaler_cfg { + /* Scaler Enable Config */ + uint32_t hEnable:1; + uint32_t vEnable:1; + uint32_t /* reserved */ : 30; + /* Scale H Image Size Config */ + uint32_t inWidth:12; + uint32_t /* reserved */ : 4; + uint32_t outWidth:12; + uint32_t /* reserved */ : 4; + /* Scale H Phase Config */ + uint32_t horizPhaseMult:18; + uint32_t /* reserved */ : 2; + uint32_t horizInterResolution:2; + uint32_t /* reserved */ : 10; + /* Scale H Stripe Config */ + uint32_t horizMNInit:12; + uint32_t /* reserved */ : 4; + uint32_t horizPhaseInit:15; + uint32_t /* reserved */ : 1; + /* Scale V Image Size Config */ + uint32_t inHeight:12; + uint32_t /* reserved */ : 4; + uint32_t outHeight:12; + uint32_t /* reserved */ : 4; + /* Scale V Phase Config */ + uint32_t vertPhaseMult:18; + uint32_t /* reserved */ : 2; + uint32_t vertInterResolution:2; + uint32_t /* reserved */ : 10; + /* Scale V Stripe Config */ + uint32_t vertMNInit:12; + uint32_t /* reserved */ : 4; + uint32_t vertPhaseInit:15; + uint32_t /* reserved */ : 1; +} __attribute__((packed, aligned(4))); + +struct vfe_scaler2_cfg { + /* Scaler Enable Config */ + uint32_t hEnable:1; + uint32_t vEnable:1; + uint32_t /* reserved */ : 30; + /* Scaler H Image Size Config */ + uint32_t inWidth:12; + uint32_t /* reserved */ : 4; + uint32_t outWidth:12; + uint32_t /* reserved */ : 4; + /* Scaler H Phase Config */ + uint32_t horizPhaseMult:18; + uint32_t /* reserved */ : 2; + uint32_t horizInterResolution:2; + uint32_t /* reserved */ : 10; + /* Scaler V Image Size Config */ + uint32_t inHeight:12; + uint32_t /* reserved */ : 4; + uint32_t outHeight:12; + uint32_t /* reserved */ : 4; + /* Scaler V Phase Config */ + uint32_t vertPhaseMult:18; + uint32_t /* reserved */ : 2; + uint32_t vertInterResolution:2; + uint32_t /* reserved */ : 10; +} __attribute__((packed, aligned(4))); + +struct vfe_rolloff_cfg { + /* Rolloff 0 Config */ + uint32_t gridWidth:9; + uint32_t gridHeight:9; + uint32_t yDelta:9; + uint32_t /* reserved */ : 5; + /* Rolloff 1 Config*/ + uint32_t gridX:4; + uint32_t gridY:4; + uint32_t pixelX:9; + uint32_t /* reserved */ : 3; + uint32_t pixelY:9; + uint32_t /* reserved */ : 3; + /* Rolloff 2 Config */ + uint32_t yDeltaAccum:12; + uint32_t /* reserved */ : 20; +} __attribute__((packed, aligned(4))); + +struct vfe_asf_update { + /* ASF Config Command */ + uint32_t smoothEnable:1; + uint32_t sharpMode:2; + uint32_t /* reserved */ : 1; + uint32_t smoothCoeff1:4; + uint32_t smoothCoeff0:8; + uint32_t pipeFlushCount:12; + uint32_t pipeFlushOvd:1; + uint32_t flushHaltOvd:1; + uint32_t cropEnable:1; + uint32_t /* reserved */ : 1; + /* Sharpening Config 0 */ + uint32_t sharpThresholdE1:7; + uint32_t /* reserved */ : 1; + uint32_t sharpDegreeK1:5; + uint32_t /* reserved */ : 3; + uint32_t sharpDegreeK2:5; + uint32_t /* reserved */ : 3; + uint32_t normalizeFactor:7; + uint32_t /* reserved */ : 1; + /* Sharpening Config 1 */ + uint32_t sharpThresholdE2:8; + uint32_t sharpThresholdE3:8; + uint32_t sharpThresholdE4:8; + uint32_t sharpThresholdE5:8; + /* Sharpening Coefficients 0 */ + uint32_t F1Coeff0:6; + uint32_t F1Coeff1:6; + uint32_t F1Coeff2:6; + uint32_t F1Coeff3:6; + uint32_t F1Coeff4:6; + uint32_t /* reserved */ : 2; + /* Sharpening Coefficients 1 */ + uint32_t F1Coeff5:6; + uint32_t F1Coeff6:6; + uint32_t F1Coeff7:6; + uint32_t F1Coeff8:7; + uint32_t /* reserved */ : 7; + /* Sharpening Coefficients 2 */ + uint32_t F2Coeff0:6; + uint32_t F2Coeff1:6; + uint32_t F2Coeff2:6; + uint32_t F2Coeff3:6; + uint32_t F2Coeff4:6; + uint32_t /* reserved */ : 2; + /* Sharpening Coefficients 3 */ + uint32_t F2Coeff5:6; + uint32_t F2Coeff6:6; + uint32_t F2Coeff7:6; + uint32_t F2Coeff8:7; + uint32_t /* reserved */ : 7; +} __attribute__((packed, aligned(4))); + +struct vfe_asfcrop_cfg { + /* ASF Crop Width Config */ + uint32_t lastPixel:12; + uint32_t /* reserved */ : 4; + uint32_t firstPixel:12; + uint32_t /* reserved */ : 4; + /* ASP Crop Height Config */ + uint32_t lastLine:12; + uint32_t /* reserved */ : 4; + uint32_t firstLine:12; + uint32_t /* reserved */ : 4; +} __attribute__((packed, aligned(4))); + +struct vfe_chroma_suppress_cfg { + /* Chroma Suppress 0 Config */ + uint32_t m1:8; + uint32_t m3:8; + uint32_t n1:3; + uint32_t /* reserved */ : 1; + uint32_t n3:3; + uint32_t /* reserved */ : 9; + /* Chroma Suppress 1 Config */ + uint32_t mm1:8; + uint32_t nn1:3; + uint32_t /* reserved */ : 21; +} __attribute__((packed, aligned(4))); + +struct vfe_chromasubsample_cfg { + /* Chroma Subsample Selection */ + uint32_t hCositedPhase:1; + uint32_t vCositedPhase:1; + uint32_t hCosited:1; + uint32_t vCosited:1; + uint32_t hsubSampleEnable:1; + uint32_t vsubSampleEnable:1; + uint32_t cropEnable:1; + uint32_t /* reserved */ : 25; + uint32_t cropWidthLastPixel:12; + uint32_t /* reserved */ : 4; + uint32_t cropWidthFirstPixel:12; + uint32_t /* reserved */ : 4; + uint32_t cropHeightLastLine:12; + uint32_t /* reserved */ : 4; + uint32_t cropHeightFirstLine:12; + uint32_t /* reserved */ : 4; +} __attribute__((packed, aligned(4))); + +struct vfe_blacklevel_cfg { + /* Black Even-Even Value Config */ + uint32_t evenEvenAdjustment:9; + uint32_t /* reserved */ : 23; + /* Black Even-Odd Value Config */ + uint32_t evenOddAdjustment:9; + uint32_t /* reserved */ : 23; + /* Black Odd-Even Value Config */ + uint32_t oddEvenAdjustment:9; + uint32_t /* reserved */ : 23; + /* Black Odd-Odd Value Config */ + uint32_t oddOddAdjustment:9; + uint32_t /* reserved */ : 23; +} __attribute__((packed, aligned(4))); + +struct vfe_demux_cfg { + /* Demux Gain 0 Config */ + uint32_t ch0EvenGain:10; + uint32_t /* reserved */ : 6; + uint32_t ch0OddGain:10; + uint32_t /* reserved */ : 6; + /* Demux Gain 1 Config */ + uint32_t ch1Gain:10; + uint32_t /* reserved */ : 6; + uint32_t ch2Gain:10; + uint32_t /* reserved */ : 6; +} __attribute__((packed, aligned(4))); + +struct vfe_bps_info { + uint32_t greenBadPixelCount:8; + uint32_t /* reserved */ : 8; + uint32_t RedBlueBadPixelCount:8; + uint32_t /* reserved */ : 8; +} __attribute__((packed, aligned(4))); + +struct vfe_demosaic_cfg { + /* Demosaic Config */ + uint32_t abfEnable:1; + uint32_t badPixelCorrEnable:1; + uint32_t forceAbfOn:1; + uint32_t /* reserved */ : 1; + uint32_t abfShift:4; + uint32_t fminThreshold:7; + uint32_t /* reserved */ : 1; + uint32_t fmaxThreshold:7; + uint32_t /* reserved */ : 5; + uint32_t slopeShift:3; + uint32_t /* reserved */ : 1; +} __attribute__((packed, aligned(4))); + +struct vfe_demosaic_bpc_cfg { + /* Demosaic BPC Config 0 */ + uint32_t blueDiffThreshold:12; + uint32_t redDiffThreshold:12; + uint32_t /* reserved */ : 8; + /* Demosaic BPC Config 1 */ + uint32_t greenDiffThreshold:12; + uint32_t /* reserved */ : 20; +} __attribute__((packed, aligned(4))); + +struct vfe_demosaic_abf_cfg { + /* Demosaic ABF Config 0 */ + uint32_t lpThreshold:10; + uint32_t /* reserved */ : 22; + /* Demosaic ABF Config 1 */ + uint32_t ratio:4; + uint32_t minValue:10; + uint32_t /* reserved */ : 2; + uint32_t maxValue:10; + uint32_t /* reserved */ : 6; +} __attribute__((packed, aligned(4))); + +struct vfe_color_correction_cfg { + /* Color Corr. Coefficient 0 Config */ + uint32_t c0:12; + uint32_t /* reserved */ : 20; + /* Color Corr. Coefficient 1 Config */ + uint32_t c1:12; + uint32_t /* reserved */ : 20; + /* Color Corr. Coefficient 2 Config */ + uint32_t c2:12; + uint32_t /* reserved */ : 20; + /* Color Corr. Coefficient 3 Config */ + uint32_t c3:12; + uint32_t /* reserved */ : 20; + /* Color Corr. Coefficient 4 Config */ + uint32_t c4:12; + uint32_t /* reserved */ : 20; + /* Color Corr. Coefficient 5 Config */ + uint32_t c5:12; + uint32_t /* reserved */ : 20; + /* Color Corr. Coefficient 6 Config */ + uint32_t c6:12; + uint32_t /* reserved */ : 20; + /* Color Corr. Coefficient 7 Config */ + uint32_t c7:12; + uint32_t /* reserved */ : 20; + /* Color Corr. Coefficient 8 Config */ + uint32_t c8:12; + uint32_t /* reserved */ : 20; + /* Color Corr. Offset 0 Config */ + uint32_t k0:11; + uint32_t /* reserved */ : 21; + /* Color Corr. Offset 1 Config */ + uint32_t k1:11; + uint32_t /* reserved */ : 21; + /* Color Corr. Offset 2 Config */ + uint32_t k2:11; + uint32_t /* reserved */ : 21; + /* Color Corr. Coefficient Q Config */ + uint32_t coefQFactor:2; + uint32_t /* reserved */ : 30; +} __attribute__((packed, aligned(4))); + +struct VFE_LumaAdaptation_ConfigCmdType { + /* LA Config */ + uint32_t lutBankSelect:1; + uint32_t /* reserved */ : 31; +} __attribute__((packed, aligned(4))); + +struct vfe_wb_cfg { + /* WB Config */ + uint32_t ch0Gain:9; + uint32_t ch1Gain:9; + uint32_t ch2Gain:9; + uint32_t /* reserved */ : 5; +} __attribute__((packed, aligned(4))); + +struct VFE_GammaLutSelect_ConfigCmdType { + /* LUT Bank Select Config */ + uint32_t ch0BankSelect:1; + uint32_t ch1BankSelect:1; + uint32_t ch2BankSelect:1; + uint32_t /* reserved */ : 29; +} __attribute__((packed, aligned(4))); + +struct vfe_chroma_enhance_cfg { + /* Chroma Enhance A Config */ + uint32_t ap:11; + uint32_t /* reserved */ : 5; + uint32_t am:11; + uint32_t /* reserved */ : 5; + /* Chroma Enhance B Config */ + uint32_t bp:11; + uint32_t /* reserved */ : 5; + uint32_t bm:11; + uint32_t /* reserved */ : 5; + /* Chroma Enhance C Config */ + uint32_t cp:11; + uint32_t /* reserved */ : 5; + uint32_t cm:11; + uint32_t /* reserved */ : 5; + /* Chroma Enhance D Config */ + uint32_t dp:11; + uint32_t /* reserved */ : 5; + uint32_t dm:11; + uint32_t /* reserved */ : 5; + /* Chroma Enhance K Config */ + uint32_t kcb:11; + uint32_t /* reserved */ : 5; + uint32_t kcr:11; + uint32_t /* reserved */ : 5; +} __attribute__((packed, aligned(4))); + +struct vfe_color_convert_cfg { + /* Conversion Coefficient 0 */ + uint32_t v0:12; + uint32_t /* reserved */ : 20; + /* Conversion Coefficient 1 */ + uint32_t v1:12; + uint32_t /* reserved */ : 20; + /* Conversion Coefficient 2 */ + uint32_t v2:12; + uint32_t /* reserved */ : 20; + /* Conversion Offset */ + uint32_t ConvertOffset:8; + uint32_t /* reserved */ : 24; +} __attribute__((packed, aligned(4))); + +struct VFE_SyncTimer_ConfigCmdType { + /* Timer Line Start Config */ + uint32_t timerLineStart:12; + uint32_t /* reserved */ : 20; + /* Timer Pixel Start Config */ + uint32_t timerPixelStart:18; + uint32_t /* reserved */ : 14; + /* Timer Pixel Duration Config */ + uint32_t timerPixelDuration:28; + uint32_t /* reserved */ : 4; + /* Sync Timer Polarity Config */ + uint32_t timer0Polarity:1; + uint32_t timer1Polarity:1; + uint32_t timer2Polarity:1; + uint32_t /* reserved */ : 29; +} __attribute__((packed, aligned(4))); + +struct VFE_AsyncTimer_ConfigCmdType { + /* Async Timer Config 0 */ + uint32_t inactiveLength:20; + uint32_t numRepetition:10; + uint32_t /* reserved */ : 1; + uint32_t polarity:1; + /* Async Timer Config 1 */ + uint32_t activeLength:20; + uint32_t /* reserved */ : 12; +} __attribute__((packed, aligned(4))); + +struct VFE_AWBAEStatistics_ConfigCmdType { + /* AWB autoexposure Config */ + uint32_t aeRegionConfig:1; + uint32_t aeSubregionConfig:1; + uint32_t /* reserved */ : 14; + uint32_t awbYMin:8; + uint32_t awbYMax:8; + /* AXW Header */ + uint32_t axwHeader:8; + uint32_t /* reserved */ : 24; + /* AWB Mconfig */ + uint32_t m4:8; + uint32_t m3:8; + uint32_t m2:8; + uint32_t m1:8; + /* AWB Cconfig */ + uint32_t c2:12; + uint32_t /* reserved */ : 4; + uint32_t c1:12; + uint32_t /* reserved */ : 4; + /* AWB Cconfig 2 */ + uint32_t c4:12; + uint32_t /* reserved */ : 4; + uint32_t c3:12; + uint32_t /* reserved */ : 4; +} __attribute__((packed, aligned(4))); + +struct VFE_TestGen_ConfigCmdType { + /* HW Test Gen Config */ + uint32_t numFrame:10; + uint32_t /* reserved */ : 2; + uint32_t pixelDataSelect:1; + uint32_t systematicDataSelect:1; + uint32_t /* reserved */ : 2; + uint32_t pixelDataSize:2; + uint32_t hsyncEdge:1; + uint32_t vsyncEdge:1; + uint32_t /* reserved */ : 12; + /* HW Test Gen Image Config */ + uint32_t imageWidth:14; + uint32_t /* reserved */ : 2; + uint32_t imageHeight:14; + uint32_t /* reserved */ : 2; + /* SOF Offset Config */ + uint32_t sofOffset:24; + uint32_t /* reserved */ : 8; + /* EOF NOffset Config */ + uint32_t eofNOffset:24; + uint32_t /* reserved */ : 8; + /* SOL Offset Config */ + uint32_t solOffset:9; + uint32_t /* reserved */ : 23; + /* EOL NOffset Config */ + uint32_t eolNOffset:9; + uint32_t /* reserved */ : 23; + /* HBI Config */ + uint32_t hBlankInterval:14; + uint32_t /* reserved */ : 18; + /* VBL Config */ + uint32_t vBlankInterval:14; + uint32_t /* reserved */ : 2; + uint32_t vBlankIntervalEnable:1; + uint32_t /* reserved */ : 15; + /* SOF Dummy Line Config */ + uint32_t sofDummy:8; + uint32_t /* reserved */ : 24; + /* EOF Dummy Line Config */ + uint32_t eofDummy:8; + uint32_t /* reserved */ : 24; + /* Color Bars Config */ + uint32_t unicolorBarSelect:3; + uint32_t /* reserved */ : 1; + uint32_t unicolorBarEnable:1; + uint32_t splitEnable:1; + uint32_t pixelPattern:2; + uint32_t rotatePeriod:6; + uint32_t /* reserved */ : 18; + /* Random Config */ + uint32_t randomSeed:16; + uint32_t /* reserved */ : 16; +} __attribute__((packed, aligned(4))); + +struct VFE_Bus_Pm_ConfigCmdType { + /* VFE Bus Performance Monitor Config */ + uint32_t output2YWrPmEnable:1; + uint32_t output2CbcrWrPmEnable:1; + uint32_t output1YWrPmEnable:1; + uint32_t output1CbcrWrPmEnable:1; + uint32_t /* reserved */ : 28; +} __attribute__((packed, aligned(4))); + +struct vfe_asf_info { + /* asf max edge */ + uint32_t maxEdge:13; + uint32_t /* reserved */ : 3; + /* HBi count */ + uint32_t HBICount:12; + uint32_t /* reserved */ : 4; +} __attribute__((packed, aligned(4))); + +struct vfe_camif_stats { + uint32_t pixelCount:14; + uint32_t /* reserved */ : 2; + uint32_t lineCount:14; + uint32_t /* reserved */ : 1; + uint32_t camifHalt:1; +} __attribute__((packed, aligned(4))); + +struct VFE_StatsCmdType { + uint32_t autoFocusEnable:1; + uint32_t axwEnable:1; + uint32_t histEnable:1; + uint32_t clearHistEnable:1; + uint32_t histAutoClearEnable:1; + uint32_t colorConversionEnable:1; + uint32_t /* reserved */ : 26; +} __attribute__((packed, aligned(4))); + + +struct vfe_statsframe { + uint32_t lastPixel:12; + uint32_t /* reserved */ : 4; + uint32_t lastLine:12; + uint32_t /* reserved */ : 4; +} __attribute__((packed, aligned(4))); + +struct vfe_busstats_wrprio { + uint32_t afBusPriority:4; + uint32_t awbBusPriority:4; + uint32_t histBusPriority:4; + uint32_t afBusPriorityEn:1; + uint32_t awbBusPriorityEn:1; + uint32_t histBusPriorityEn:1; + uint32_t /* reserved */ : 17; +} __attribute__((packed, aligned(4))); + +struct vfe_statsaf_update { + /* VFE_STATS_AF_CFG */ + uint32_t windowVOffset:12; + uint32_t /* reserved */ : 4; + uint32_t windowHOffset:12; + uint32_t /* reserved */ : 3; + uint32_t windowMode:1; + + /* VFE_STATS_AF_DIM */ + uint32_t windowHeight:12; + uint32_t /* reserved */ : 4; + uint32_t windowWidth:12; + uint32_t /* reserved */ : 4; +} __attribute__((packed, aligned(4))); + +struct vfe_statsaf_cfg { + /* VFE_STATS_AF_GRID_0 */ + uint32_t entry00:8; + uint32_t entry01:8; + uint32_t entry02:8; + uint32_t entry03:8; + + /* VFE_STATS_AF_GRID_1 */ + uint32_t entry10:8; + uint32_t entry11:8; + uint32_t entry12:8; + uint32_t entry13:8; + + /* VFE_STATS_AF_GRID_2 */ + uint32_t entry20:8; + uint32_t entry21:8; + uint32_t entry22:8; + uint32_t entry23:8; + + /* VFE_STATS_AF_GRID_3 */ + uint32_t entry30:8; + uint32_t entry31:8; + uint32_t entry32:8; + uint32_t entry33:8; + + /* VFE_STATS_AF_HEADER */ + uint32_t afHeader:8; + uint32_t /* reserved */ : 24; + /* VFE_STATS_AF_COEF0 */ + uint32_t a00:5; + uint32_t a04:5; + uint32_t fvMax:11; + uint32_t fvMetric:1; + uint32_t /* reserved */ : 10; + + /* VFE_STATS_AF_COEF1 */ + uint32_t a20:5; + uint32_t a21:5; + uint32_t a22:5; + uint32_t a23:5; + uint32_t a24:5; + uint32_t /* reserved */ : 7; +} __attribute__((packed, aligned(4))); + +struct vfe_statsawbae_update { + uint32_t aeRegionCfg:1; + uint32_t aeSubregionCfg:1; + uint32_t /* reserved */ : 14; + uint32_t awbYMin:8; + uint32_t awbYMax:8; +} __attribute__((packed, aligned(4))); + +struct vfe_statsaxw_hdr_cfg { + /* Stats AXW Header Config */ + uint32_t axwHeader:8; + uint32_t /* reserved */ : 24; +} __attribute__((packed, aligned(4))); + +struct vfe_statsawb_update { + /* AWB MConfig */ + uint32_t m4:8; + uint32_t m3:8; + uint32_t m2:8; + uint32_t m1:8; + + /* AWB CConfig1 */ + uint32_t c2:12; + uint32_t /* reserved */ : 4; + uint32_t c1:12; + uint32_t /* reserved */ : 4; + + /* AWB CConfig2 */ + uint32_t c4:12; + uint32_t /* reserved */ : 4; + uint32_t c3:12; + uint32_t /* reserved */ : 4; +} __attribute__((packed, aligned(4))); + +struct VFE_SyncTimerCmdType { + uint32_t hsyncCount:12; + uint32_t /* reserved */ : 20; + uint32_t pclkCount:18; + uint32_t /* reserved */ : 14; + uint32_t outputDuration:28; + uint32_t /* reserved */ : 4; +} __attribute__((packed, aligned(4))); + +struct VFE_AsyncTimerCmdType { + /* config 0 */ + uint32_t inactiveCount:20; + uint32_t repeatCount:10; + uint32_t /* reserved */ : 1; + uint32_t polarity:1; + /* config 1 */ + uint32_t activeCount:20; + uint32_t /* reserved */ : 12; +} __attribute__((packed, aligned(4))); + +struct VFE_AxiInputCmdType { + uint32_t stripeStartAddr0:32; + uint32_t stripeStartAddr1:32; + uint32_t stripeStartAddr2:32; + uint32_t stripeStartAddr3:32; + + uint32_t ySize:12; + uint32_t yOffsetDelta:12; + uint32_t /* reserved */ : 8; + + /* bus_stripe_rd_hSize */ + uint32_t /* reserved */ : 16; + uint32_t xSizeWord:10; + uint32_t /* reserved */ : 6; + + /* bus_stripe_rd_buffer_cfg */ + uint32_t burstLength:2; + uint32_t /* reserved */ : 2; + uint32_t NumOfRows:12; + uint32_t RowIncrement:12; + uint32_t /* reserved */ : 4; + + /* bus_stripe_rd_unpack_cfg */ + uint32_t mainUnpackHeight:12; + uint32_t mainUnpackWidth:13; + uint32_t mainUnpackHbiSel:3; + uint32_t mainUnpackPhase:3; + uint32_t /* reserved */ : 1; + + /* bus_stripe_rd_unpack */ + uint32_t unpackPattern:32; + + /* bus_stripe_rd_pad_size */ + uint32_t padLeft:7; + uint32_t /* reserved */ : 1; + uint32_t padRight:7; + uint32_t /* reserved */ : 1; + uint32_t padTop:7; + uint32_t /* reserved */ : 1; + uint32_t padBottom:7; + uint32_t /* reserved */ : 1; + + /* bus_stripe_rd_pad_L_unpack */ + uint32_t leftUnpackPattern0:4; + uint32_t leftUnpackPattern1:4; + uint32_t leftUnpackPattern2:4; + uint32_t leftUnpackPattern3:4; + uint32_t leftUnpackStop0:1; + uint32_t leftUnpackStop1:1; + uint32_t leftUnpackStop2:1; + uint32_t leftUnpackStop3:1; + uint32_t /* reserved */ : 12; + + /* bus_stripe_rd_pad_R_unpack */ + uint32_t rightUnpackPattern0:4; + uint32_t rightUnpackPattern1:4; + uint32_t rightUnpackPattern2:4; + uint32_t rightUnpackPattern3:4; + uint32_t rightUnpackStop0:1; + uint32_t rightUnpackStop1:1; + uint32_t rightUnpackStop2:1; + uint32_t rightUnpackStop3:1; + uint32_t /* reserved */ : 12; + + /* bus_stripe_rd_pad_tb_unpack */ + uint32_t topUnapckPattern:4; + uint32_t /* reserved */ : 12; + uint32_t bottomUnapckPattern:4; + uint32_t /* reserved */ : 12; +} __attribute__((packed, aligned(4))); + +struct VFE_AxiRdFragIrqEnable { + uint32_t stripeRdFragirq0Enable:1; + uint32_t stripeRdFragirq1Enable:1; + uint32_t stripeRdFragirq2Enable:1; + uint32_t stripeRdFragirq3Enable:1; + uint32_t /* reserved */ : 28; +} __attribute__((packed, aligned(4))); + +int vfe_cmd_init(struct msm_vfe_callback *, struct platform_device *, void *); +void vfe_stats_af_stop(void); +void vfe_stop(void); +void vfe_update(void); +int vfe_rgb_gamma_update(struct vfe_cmd_rgb_gamma_config *); +int vfe_rgb_gamma_config(struct vfe_cmd_rgb_gamma_config *); +void vfe_stats_wb_exp_ack(struct vfe_cmd_stats_wb_exp_ack *); +void vfe_stats_af_ack(struct vfe_cmd_stats_af_ack *); +void vfe_start(struct vfe_cmd_start *); +void vfe_la_update(struct vfe_cmd_la_config *); +void vfe_la_config(struct vfe_cmd_la_config *); +void vfe_test_gen_start(struct vfe_cmd_test_gen_start *); +void vfe_frame_skip_update(struct vfe_cmd_frame_skip_update *); +void vfe_frame_skip_config(struct vfe_cmd_frame_skip_config *); +void vfe_output_clamp_config(struct vfe_cmd_output_clamp_config *); +void vfe_camif_frame_update(struct vfe_cmds_camif_frame *); +void vfe_color_correction_config(struct vfe_cmd_color_correction_config *); +void vfe_demosaic_abf_update(struct vfe_cmd_demosaic_abf_update *); +void vfe_demosaic_bpc_update(struct vfe_cmd_demosaic_bpc_update *); +void vfe_demosaic_config(struct vfe_cmd_demosaic_config *); +void vfe_demux_channel_gain_update(struct vfe_cmd_demux_channel_gain_config *); +void vfe_demux_channel_gain_config(struct vfe_cmd_demux_channel_gain_config *); +void vfe_black_level_update(struct vfe_cmd_black_level_config *); +void vfe_black_level_config(struct vfe_cmd_black_level_config *); +void vfe_asf_update(struct vfe_cmd_asf_update *); +void vfe_asf_config(struct vfe_cmd_asf_config *); +void vfe_white_balance_config(struct vfe_cmd_white_balance_config *); +void vfe_chroma_sup_config(struct vfe_cmd_chroma_suppression_config *); +void vfe_roll_off_config(struct vfe_cmd_roll_off_config *); +void vfe_chroma_subsample_config(struct vfe_cmd_chroma_subsample_config *); +void vfe_chroma_enhan_config(struct vfe_cmd_chroma_enhan_config *); +void vfe_scaler2cbcr_config(struct vfe_cmd_scaler2_config *); +void vfe_scaler2y_config(struct vfe_cmd_scaler2_config *); +void vfe_main_scaler_config(struct vfe_cmd_main_scaler_config *); +void vfe_stats_wb_exp_stop(void); +void vfe_stats_update_wb_exp(struct vfe_cmd_stats_wb_exp_update *); +void vfe_stats_update_af(struct vfe_cmd_stats_af_update *); +void vfe_stats_start_wb_exp(struct vfe_cmd_stats_wb_exp_start *); +void vfe_stats_start_af(struct vfe_cmd_stats_af_start *); +void vfe_stats_setting(struct vfe_cmd_stats_setting *); +void vfe_axi_input_config(struct vfe_cmd_axi_input_config *); +void vfe_stats_config(struct vfe_cmd_stats_setting *); +void vfe_axi_output_config(struct vfe_cmd_axi_output_config *); +void vfe_camif_config(struct vfe_cmd_camif_config *); +void vfe_fov_crop_config(struct vfe_cmd_fov_crop_config *); +void vfe_get_hw_version(struct vfe_cmd_hw_version *); +void vfe_reset(void); +void vfe_cmd_release(struct platform_device *); +void vfe_output1_ack(struct vfe_cmd_output_ack *); +void vfe_output2_ack(struct vfe_cmd_output_ack *); +#endif /* __MSM_VFE8X_REG_H__ */ diff --git a/trunk/drivers/staging/dream/camera/mt9d112.c b/trunk/drivers/staging/dream/camera/mt9d112.c new file mode 100644 index 000000000000..e6f2d5124611 --- /dev/null +++ b/trunk/drivers/staging/dream/camera/mt9d112.c @@ -0,0 +1,762 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "mt9d112.h" + +/* Micron MT9D112 Registers and their values */ +/* Sensor Core Registers */ +#define REG_MT9D112_MODEL_ID 0x3000 +#define MT9D112_MODEL_ID 0x1580 + +/* SOC Registers Page 1 */ +#define REG_MT9D112_SENSOR_RESET 0x301A +#define REG_MT9D112_STANDBY_CONTROL 0x3202 +#define REG_MT9D112_MCU_BOOT 0x3386 + +struct mt9d112_work { + struct work_struct work; +}; + +static struct mt9d112_work *mt9d112_sensorw; +static struct i2c_client *mt9d112_client; + +struct mt9d112_ctrl { + const struct msm_camera_sensor_info *sensordata; +}; + + +static struct mt9d112_ctrl *mt9d112_ctrl; + +static DECLARE_WAIT_QUEUE_HEAD(mt9d112_wait_queue); +DECLARE_MUTEX(mt9d112_sem); + + +/*============================================================= + EXTERNAL DECLARATIONS +==============================================================*/ +extern struct mt9d112_reg mt9d112_regs; + + +/*=============================================================*/ + +static int mt9d112_reset(const struct msm_camera_sensor_info *dev) +{ + int rc = 0; + + rc = gpio_request(dev->sensor_reset, "mt9d112"); + + if (!rc) { + rc = gpio_direction_output(dev->sensor_reset, 0); + mdelay(20); + rc = gpio_direction_output(dev->sensor_reset, 1); + } + + gpio_free(dev->sensor_reset); + return rc; +} + +static int32_t mt9d112_i2c_txdata(unsigned short saddr, + unsigned char *txdata, int length) +{ + struct i2c_msg msg[] = { + { + .addr = saddr, + .flags = 0, + .len = length, + .buf = txdata, + }, + }; + + if (i2c_transfer(mt9d112_client->adapter, msg, 1) < 0) { + CDBG("mt9d112_i2c_txdata failed\n"); + return -EIO; + } + + return 0; +} + +static int32_t mt9d112_i2c_write(unsigned short saddr, + unsigned short waddr, unsigned short wdata, enum mt9d112_width width) +{ + int32_t rc = -EIO; + unsigned char buf[4]; + + memset(buf, 0, sizeof(buf)); + switch (width) { + case WORD_LEN: { + buf[0] = (waddr & 0xFF00)>>8; + buf[1] = (waddr & 0x00FF); + buf[2] = (wdata & 0xFF00)>>8; + buf[3] = (wdata & 0x00FF); + + rc = mt9d112_i2c_txdata(saddr, buf, 4); + } + break; + + case BYTE_LEN: { + buf[0] = waddr; + buf[1] = wdata; + rc = mt9d112_i2c_txdata(saddr, buf, 2); + } + break; + + default: + break; + } + + if (rc < 0) + CDBG( + "i2c_write failed, addr = 0x%x, val = 0x%x!\n", + waddr, wdata); + + return rc; +} + +static int32_t mt9d112_i2c_write_table( + struct mt9d112_i2c_reg_conf const *reg_conf_tbl, + int num_of_items_in_table) +{ + int i; + int32_t rc = -EIO; + + for (i = 0; i < num_of_items_in_table; i++) { + rc = mt9d112_i2c_write(mt9d112_client->addr, + reg_conf_tbl->waddr, reg_conf_tbl->wdata, + reg_conf_tbl->width); + if (rc < 0) + break; + if (reg_conf_tbl->mdelay_time != 0) + mdelay(reg_conf_tbl->mdelay_time); + reg_conf_tbl++; + } + + return rc; +} + +static int mt9d112_i2c_rxdata(unsigned short saddr, + unsigned char *rxdata, int length) +{ + struct i2c_msg msgs[] = { + { + .addr = saddr, + .flags = 0, + .len = 2, + .buf = rxdata, + }, + { + .addr = saddr, + .flags = I2C_M_RD, + .len = length, + .buf = rxdata, + }, + }; + + if (i2c_transfer(mt9d112_client->adapter, msgs, 2) < 0) { + CDBG("mt9d112_i2c_rxdata failed!\n"); + return -EIO; + } + + return 0; +} + +static int32_t mt9d112_i2c_read(unsigned short saddr, + unsigned short raddr, unsigned short *rdata, enum mt9d112_width width) +{ + int32_t rc = 0; + unsigned char buf[4]; + + if (!rdata) + return -EIO; + + memset(buf, 0, sizeof(buf)); + + switch (width) { + case WORD_LEN: { + buf[0] = (raddr & 0xFF00)>>8; + buf[1] = (raddr & 0x00FF); + + rc = mt9d112_i2c_rxdata(saddr, buf, 2); + if (rc < 0) + return rc; + + *rdata = buf[0] << 8 | buf[1]; + } + break; + + default: + break; + } + + if (rc < 0) + CDBG("mt9d112_i2c_read failed!\n"); + + return rc; +} + +static int32_t mt9d112_set_lens_roll_off(void) +{ + int32_t rc = 0; + rc = mt9d112_i2c_write_table(&mt9d112_regs.rftbl[0], + mt9d112_regs.rftbl_size); + return rc; +} + +static long mt9d112_reg_init(void) +{ + int32_t array_length; + int32_t i; + long rc; + + /* PLL Setup Start */ + rc = mt9d112_i2c_write_table(&mt9d112_regs.plltbl[0], + mt9d112_regs.plltbl_size); + + if (rc < 0) + return rc; + /* PLL Setup End */ + + array_length = mt9d112_regs.prev_snap_reg_settings_size; + + /* Configure sensor for Preview mode and Snapshot mode */ + for (i = 0; i < array_length; i++) { + rc = mt9d112_i2c_write(mt9d112_client->addr, + mt9d112_regs.prev_snap_reg_settings[i].register_address, + mt9d112_regs.prev_snap_reg_settings[i].register_value, + WORD_LEN); + + if (rc < 0) + return rc; + } + + /* Configure for Noise Reduction, Saturation and Aperture Correction */ + array_length = mt9d112_regs.noise_reduction_reg_settings_size; + + for (i = 0; i < array_length; i++) { + rc = mt9d112_i2c_write(mt9d112_client->addr, + mt9d112_regs.noise_reduction_reg_settings[i].register_address, + mt9d112_regs.noise_reduction_reg_settings[i].register_value, + WORD_LEN); + + if (rc < 0) + return rc; + } + + /* Set Color Kill Saturation point to optimum value */ + rc = + mt9d112_i2c_write(mt9d112_client->addr, + 0x35A4, + 0x0593, + WORD_LEN); + if (rc < 0) + return rc; + + rc = mt9d112_i2c_write_table(&mt9d112_regs.stbl[0], + mt9d112_regs.stbl_size); + if (rc < 0) + return rc; + + rc = mt9d112_set_lens_roll_off(); + if (rc < 0) + return rc; + + return 0; +} + +static long mt9d112_set_sensor_mode(int mode) +{ + uint16_t clock; + long rc = 0; + + switch (mode) { + case SENSOR_PREVIEW_MODE: + rc = + mt9d112_i2c_write(mt9d112_client->addr, + 0x338C, 0xA20C, WORD_LEN); + if (rc < 0) + return rc; + + rc = + mt9d112_i2c_write(mt9d112_client->addr, + 0x3390, 0x0004, WORD_LEN); + if (rc < 0) + return rc; + + rc = + mt9d112_i2c_write(mt9d112_client->addr, + 0x338C, 0xA215, WORD_LEN); + if (rc < 0) + return rc; + + rc = + mt9d112_i2c_write(mt9d112_client->addr, + 0x3390, 0x0004, WORD_LEN); + if (rc < 0) + return rc; + + rc = + mt9d112_i2c_write(mt9d112_client->addr, + 0x338C, 0xA20B, WORD_LEN); + if (rc < 0) + return rc; + + rc = + mt9d112_i2c_write(mt9d112_client->addr, + 0x3390, 0x0000, WORD_LEN); + if (rc < 0) + return rc; + + clock = 0x0250; + + rc = + mt9d112_i2c_write(mt9d112_client->addr, + 0x341C, clock, WORD_LEN); + if (rc < 0) + return rc; + + rc = + mt9d112_i2c_write(mt9d112_client->addr, + 0x338C, 0xA103, WORD_LEN); + if (rc < 0) + return rc; + + rc = + mt9d112_i2c_write(mt9d112_client->addr, + 0x3390, 0x0001, WORD_LEN); + if (rc < 0) + return rc; + + mdelay(5); + break; + + case SENSOR_SNAPSHOT_MODE: + /* Switch to lower fps for Snapshot */ + rc = + mt9d112_i2c_write(mt9d112_client->addr, + 0x341C, 0x0120, WORD_LEN); + if (rc < 0) + return rc; + + rc = + mt9d112_i2c_write(mt9d112_client->addr, + 0x338C, 0xA120, WORD_LEN); + if (rc < 0) + return rc; + + rc = + mt9d112_i2c_write(mt9d112_client->addr, + 0x3390, 0x0002, WORD_LEN); + if (rc < 0) + return rc; + + mdelay(5); + + rc = + mt9d112_i2c_write(mt9d112_client->addr, + 0x338C, 0xA103, WORD_LEN); + if (rc < 0) + return rc; + + rc = + mt9d112_i2c_write(mt9d112_client->addr, + 0x3390, 0x0002, WORD_LEN); + if (rc < 0) + return rc; + break; + + default: + return -EINVAL; + } + + return 0; +} + +static long mt9d112_set_effect(int mode, int effect) +{ + uint16_t reg_addr; + uint16_t reg_val; + long rc = 0; + + switch (mode) { + case SENSOR_PREVIEW_MODE: + /* Context A Special Effects */ + reg_addr = 0x2799; + break; + + case SENSOR_SNAPSHOT_MODE: + /* Context B Special Effects */ + reg_addr = 0x279B; + break; + + default: + reg_addr = 0x2799; + break; + } + + switch (effect) { + case CAMERA_EFFECT_OFF: { + reg_val = 0x6440; + + rc = mt9d112_i2c_write(mt9d112_client->addr, + 0x338C, reg_addr, WORD_LEN); + if (rc < 0) + return rc; + + rc = mt9d112_i2c_write(mt9d112_client->addr, + 0x3390, reg_val, WORD_LEN); + if (rc < 0) + return rc; + } + break; + + case CAMERA_EFFECT_MONO: { + reg_val = 0x6441; + rc = mt9d112_i2c_write(mt9d112_client->addr, + 0x338C, reg_addr, WORD_LEN); + if (rc < 0) + return rc; + + rc = mt9d112_i2c_write(mt9d112_client->addr, + 0x3390, reg_val, WORD_LEN); + if (rc < 0) + return rc; + } + break; + + case CAMERA_EFFECT_NEGATIVE: { + reg_val = 0x6443; + rc = mt9d112_i2c_write(mt9d112_client->addr, + 0x338C, reg_addr, WORD_LEN); + if (rc < 0) + return rc; + + rc = mt9d112_i2c_write(mt9d112_client->addr, + 0x3390, reg_val, WORD_LEN); + if (rc < 0) + return rc; + } + break; + + case CAMERA_EFFECT_SOLARIZE: { + reg_val = 0x6445; + rc = mt9d112_i2c_write(mt9d112_client->addr, + 0x338C, reg_addr, WORD_LEN); + if (rc < 0) + return rc; + + rc = mt9d112_i2c_write(mt9d112_client->addr, + 0x3390, reg_val, WORD_LEN); + if (rc < 0) + return rc; + } + break; + + case CAMERA_EFFECT_SEPIA: { + reg_val = 0x6442; + rc = mt9d112_i2c_write(mt9d112_client->addr, + 0x338C, reg_addr, WORD_LEN); + if (rc < 0) + return rc; + + rc = mt9d112_i2c_write(mt9d112_client->addr, + 0x3390, reg_val, WORD_LEN); + if (rc < 0) + return rc; + } + break; + + case CAMERA_EFFECT_PASTEL: + case CAMERA_EFFECT_MOSAIC: + case CAMERA_EFFECT_RESIZE: + return -EINVAL; + + default: { + reg_val = 0x6440; + rc = mt9d112_i2c_write(mt9d112_client->addr, + 0x338C, reg_addr, WORD_LEN); + if (rc < 0) + return rc; + + rc = mt9d112_i2c_write(mt9d112_client->addr, + 0x3390, reg_val, WORD_LEN); + if (rc < 0) + return rc; + + return -EINVAL; + } + } + + /* Refresh Sequencer */ + rc = mt9d112_i2c_write(mt9d112_client->addr, + 0x338C, 0xA103, WORD_LEN); + if (rc < 0) + return rc; + + rc = mt9d112_i2c_write(mt9d112_client->addr, + 0x3390, 0x0005, WORD_LEN); + + return rc; +} + +static int mt9d112_sensor_init_probe(const struct msm_camera_sensor_info *data) +{ + uint16_t model_id = 0; + int rc = 0; + + CDBG("init entry \n"); + rc = mt9d112_reset(data); + if (rc < 0) { + CDBG("reset failed!\n"); + goto init_probe_fail; + } + + mdelay(5); + + /* Micron suggested Power up block Start: + * Put MCU into Reset - Stop MCU */ + rc = mt9d112_i2c_write(mt9d112_client->addr, + REG_MT9D112_MCU_BOOT, 0x0501, WORD_LEN); + if (rc < 0) + goto init_probe_fail; + + /* Pull MCU from Reset - Start MCU */ + rc = mt9d112_i2c_write(mt9d112_client->addr, + REG_MT9D112_MCU_BOOT, 0x0500, WORD_LEN); + if (rc < 0) + goto init_probe_fail; + + mdelay(5); + + /* Micron Suggested - Power up block */ + rc = mt9d112_i2c_write(mt9d112_client->addr, + REG_MT9D112_SENSOR_RESET, 0x0ACC, WORD_LEN); + if (rc < 0) + goto init_probe_fail; + + rc = mt9d112_i2c_write(mt9d112_client->addr, + REG_MT9D112_STANDBY_CONTROL, 0x0008, WORD_LEN); + if (rc < 0) + goto init_probe_fail; + + /* FUSED_DEFECT_CORRECTION */ + rc = mt9d112_i2c_write(mt9d112_client->addr, + 0x33F4, 0x031D, WORD_LEN); + if (rc < 0) + goto init_probe_fail; + + mdelay(5); + + /* Micron suggested Power up block End */ + /* Read the Model ID of the sensor */ + rc = mt9d112_i2c_read(mt9d112_client->addr, + REG_MT9D112_MODEL_ID, &model_id, WORD_LEN); + if (rc < 0) + goto init_probe_fail; + + CDBG("mt9d112 model_id = 0x%x\n", model_id); + + /* Check if it matches it with the value in Datasheet */ + if (model_id != MT9D112_MODEL_ID) { + rc = -EINVAL; + goto init_probe_fail; + } + + rc = mt9d112_reg_init(); + if (rc < 0) + goto init_probe_fail; + + return rc; + +init_probe_fail: + return rc; +} + +int mt9d112_sensor_init(const struct msm_camera_sensor_info *data) +{ + int rc = 0; + + mt9d112_ctrl = kzalloc(sizeof(struct mt9d112_ctrl), GFP_KERNEL); + if (!mt9d112_ctrl) { + CDBG("mt9d112_init failed!\n"); + rc = -ENOMEM; + goto init_done; + } + + if (data) + mt9d112_ctrl->sensordata = data; + + /* Input MCLK = 24MHz */ + msm_camio_clk_rate_set(24000000); + mdelay(5); + + msm_camio_camif_pad_reg_reset(); + + rc = mt9d112_sensor_init_probe(data); + if (rc < 0) { + CDBG("mt9d112_sensor_init failed!\n"); + goto init_fail; + } + +init_done: + return rc; + +init_fail: + kfree(mt9d112_ctrl); + return rc; +} + +static int mt9d112_init_client(struct i2c_client *client) +{ + /* Initialize the MSM_CAMI2C Chip */ + init_waitqueue_head(&mt9d112_wait_queue); + return 0; +} + +int mt9d112_sensor_config(void __user *argp) +{ + struct sensor_cfg_data cfg_data; + long rc = 0; + + if (copy_from_user(&cfg_data, + (void *)argp, + sizeof(struct sensor_cfg_data))) + return -EFAULT; + + /* down(&mt9d112_sem); */ + + CDBG("mt9d112_ioctl, cfgtype = %d, mode = %d\n", + cfg_data.cfgtype, cfg_data.mode); + + switch (cfg_data.cfgtype) { + case CFG_SET_MODE: + rc = mt9d112_set_sensor_mode( + cfg_data.mode); + break; + + case CFG_SET_EFFECT: + rc = mt9d112_set_effect(cfg_data.mode, + cfg_data.cfg.effect); + break; + + case CFG_GET_AF_MAX_STEPS: + default: + rc = -EINVAL; + break; + } + + /* up(&mt9d112_sem); */ + + return rc; +} + +int mt9d112_sensor_release(void) +{ + int rc = 0; + + /* down(&mt9d112_sem); */ + + kfree(mt9d112_ctrl); + /* up(&mt9d112_sem); */ + + return rc; +} + +static int mt9d112_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int rc = 0; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + rc = -ENOTSUPP; + goto probe_failure; + } + + mt9d112_sensorw = + kzalloc(sizeof(struct mt9d112_work), GFP_KERNEL); + + if (!mt9d112_sensorw) { + rc = -ENOMEM; + goto probe_failure; + } + + i2c_set_clientdata(client, mt9d112_sensorw); + mt9d112_init_client(client); + mt9d112_client = client; + + CDBG("mt9d112_probe succeeded!\n"); + + return 0; + +probe_failure: + kfree(mt9d112_sensorw); + mt9d112_sensorw = NULL; + CDBG("mt9d112_probe failed!\n"); + return rc; +} + +static const struct i2c_device_id mt9d112_i2c_id[] = { + { "mt9d112", 0}, + { }, +}; + +static struct i2c_driver mt9d112_i2c_driver = { + .id_table = mt9d112_i2c_id, + .probe = mt9d112_i2c_probe, + .remove = __exit_p(mt9d112_i2c_remove), + .driver = { + .name = "mt9d112", + }, +}; + +static int mt9d112_sensor_probe(const struct msm_camera_sensor_info *info, + struct msm_sensor_ctrl *s) +{ + int rc = i2c_add_driver(&mt9d112_i2c_driver); + if (rc < 0 || mt9d112_client == NULL) { + rc = -ENOTSUPP; + goto probe_done; + } + + /* Input MCLK = 24MHz */ + msm_camio_clk_rate_set(24000000); + mdelay(5); + + rc = mt9d112_sensor_init_probe(info); + if (rc < 0) + goto probe_done; + + s->s_init = mt9d112_sensor_init; + s->s_release = mt9d112_sensor_release; + s->s_config = mt9d112_sensor_config; + +probe_done: + CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__); + return rc; +} + +static int __mt9d112_probe(struct platform_device *pdev) +{ + return msm_camera_drv_start(pdev, mt9d112_sensor_probe); +} + +static struct platform_driver msm_camera_driver = { + .probe = __mt9d112_probe, + .driver = { + .name = "msm_camera_mt9d112", + .owner = THIS_MODULE, + }, +}; + +static int __init mt9d112_init(void) +{ + return platform_driver_register(&msm_camera_driver); +} + +module_init(mt9d112_init); diff --git a/trunk/drivers/staging/dream/camera/mt9d112.h b/trunk/drivers/staging/dream/camera/mt9d112.h new file mode 100644 index 000000000000..c678996f9e2b --- /dev/null +++ b/trunk/drivers/staging/dream/camera/mt9d112.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ + +#ifndef MT9D112_H +#define MT9D112_H + +#include +#include + +enum mt9d112_width { + WORD_LEN, + BYTE_LEN +}; + +struct mt9d112_i2c_reg_conf { + unsigned short waddr; + unsigned short wdata; + enum mt9d112_width width; + unsigned short mdelay_time; +}; + +struct mt9d112_reg { + const struct register_address_value_pair *prev_snap_reg_settings; + uint16_t prev_snap_reg_settings_size; + const struct register_address_value_pair *noise_reduction_reg_settings; + uint16_t noise_reduction_reg_settings_size; + const struct mt9d112_i2c_reg_conf *plltbl; + uint16_t plltbl_size; + const struct mt9d112_i2c_reg_conf *stbl; + uint16_t stbl_size; + const struct mt9d112_i2c_reg_conf *rftbl; + uint16_t rftbl_size; +}; + +#endif /* MT9D112_H */ diff --git a/trunk/drivers/staging/dream/camera/mt9d112_reg.c b/trunk/drivers/staging/dream/camera/mt9d112_reg.c new file mode 100644 index 000000000000..c52e96f47141 --- /dev/null +++ b/trunk/drivers/staging/dream/camera/mt9d112_reg.c @@ -0,0 +1,307 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ + +#include "mt9d112.h" + +struct register_address_value_pair +preview_snapshot_mode_reg_settings_array[] = { + {0x338C, 0x2703}, + {0x3390, 800}, /* Output Width (P) = 640 */ + {0x338C, 0x2705}, + {0x3390, 600}, /* Output Height (P) = 480 */ + {0x338C, 0x2707}, + {0x3390, 0x0640}, /* Output Width (S) = 1600 */ + {0x338C, 0x2709}, + {0x3390, 0x04B0}, /* Output Height (S) = 1200 */ + {0x338C, 0x270D}, + {0x3390, 0x0000}, /* Row Start (P) = 0 */ + {0x338C, 0x270F}, + {0x3390, 0x0000}, /* Column Start (P) = 0 */ + {0x338C, 0x2711}, + {0x3390, 0x04BD}, /* Row End (P) = 1213 */ + {0x338C, 0x2713}, + {0x3390, 0x064D}, /* Column End (P) = 1613 */ + {0x338C, 0x2715}, + {0x3390, 0x0000}, /* Extra Delay (P) = 0 */ + {0x338C, 0x2717}, + {0x3390, 0x2111}, /* Row Speed (P) = 8465 */ + {0x338C, 0x2719}, + {0x3390, 0x046C}, /* Read Mode (P) = 1132 */ + {0x338C, 0x271B}, + {0x3390, 0x024F}, /* Sensor_Sample_Time_pck(P) = 591 */ + {0x338C, 0x271D}, + {0x3390, 0x0102}, /* Sensor_Fine_Correction(P) = 258 */ + {0x338C, 0x271F}, + {0x3390, 0x0279}, /* Sensor_Fine_IT_min(P) = 633 */ + {0x338C, 0x2721}, + {0x3390, 0x0155}, /* Sensor_Fine_IT_max_margin(P) = 341 */ + {0x338C, 0x2723}, + {0x3390, 659}, /* Frame Lines (P) = 679 */ + {0x338C, 0x2725}, + {0x3390, 0x0824}, /* Line Length (P) = 2084 */ + {0x338C, 0x2727}, + {0x3390, 0x2020}, + {0x338C, 0x2729}, + {0x3390, 0x2020}, + {0x338C, 0x272B}, + {0x3390, 0x1020}, + {0x338C, 0x272D}, + {0x3390, 0x2007}, + {0x338C, 0x272F}, + {0x3390, 0x0004}, /* Row Start(S) = 4 */ + {0x338C, 0x2731}, + {0x3390, 0x0004}, /* Column Start(S) = 4 */ + {0x338C, 0x2733}, + {0x3390, 0x04BB}, /* Row End(S) = 1211 */ + {0x338C, 0x2735}, + {0x3390, 0x064B}, /* Column End(S) = 1611 */ + {0x338C, 0x2737}, + {0x3390, 0x04CE}, /* Extra Delay(S) = 1230 */ + {0x338C, 0x2739}, + {0x3390, 0x2111}, /* Row Speed(S) = 8465 */ + {0x338C, 0x273B}, + {0x3390, 0x0024}, /* Read Mode(S) = 36 */ + {0x338C, 0x273D}, + {0x3390, 0x0120}, /* Sensor sample time pck(S) = 288 */ + {0x338C, 0x2741}, + {0x3390, 0x0169}, /* Sensor_Fine_IT_min(P) = 361 */ + {0x338C, 0x2745}, + {0x3390, 0x04FF}, /* Frame Lines(S) = 1279 */ + {0x338C, 0x2747}, + {0x3390, 0x0824}, /* Line Length(S) = 2084 */ + {0x338C, 0x2751}, + {0x3390, 0x0000}, /* Crop_X0(P) = 0 */ + {0x338C, 0x2753}, + {0x3390, 0x0320}, /* Crop_X1(P) = 800 */ + {0x338C, 0x2755}, + {0x3390, 0x0000}, /* Crop_Y0(P) = 0 */ + {0x338C, 0x2757}, + {0x3390, 0x0258}, /* Crop_Y1(P) = 600 */ + {0x338C, 0x275F}, + {0x3390, 0x0000}, /* Crop_X0(S) = 0 */ + {0x338C, 0x2761}, + {0x3390, 0x0640}, /* Crop_X1(S) = 1600 */ + {0x338C, 0x2763}, + {0x3390, 0x0000}, /* Crop_Y0(S) = 0 */ + {0x338C, 0x2765}, + {0x3390, 0x04B0}, /* Crop_Y1(S) = 1200 */ + {0x338C, 0x222E}, + {0x3390, 0x00A0}, /* R9 Step = 160 */ + {0x338C, 0xA408}, + {0x3390, 0x001F}, + {0x338C, 0xA409}, + {0x3390, 0x0021}, + {0x338C, 0xA40A}, + {0x3390, 0x0025}, + {0x338C, 0xA40B}, + {0x3390, 0x0027}, + {0x338C, 0x2411}, + {0x3390, 0x00A0}, + {0x338C, 0x2413}, + {0x3390, 0x00C0}, + {0x338C, 0x2415}, + {0x3390, 0x00A0}, + {0x338C, 0x2417}, + {0x3390, 0x00C0}, + {0x338C, 0x2799}, + {0x3390, 0x6408}, /* MODE_SPEC_EFFECTS(P) */ + {0x338C, 0x279B}, + {0x3390, 0x6408}, /* MODE_SPEC_EFFECTS(S) */ +}; + +static struct register_address_value_pair +noise_reduction_reg_settings_array[] = { + {0x338C, 0xA76D}, + {0x3390, 0x0003}, + {0x338C, 0xA76E}, + {0x3390, 0x0003}, + {0x338C, 0xA76F}, + {0x3390, 0}, + {0x338C, 0xA770}, + {0x3390, 21}, + {0x338C, 0xA771}, + {0x3390, 37}, + {0x338C, 0xA772}, + {0x3390, 63}, + {0x338C, 0xA773}, + {0x3390, 100}, + {0x338C, 0xA774}, + {0x3390, 128}, + {0x338C, 0xA775}, + {0x3390, 151}, + {0x338C, 0xA776}, + {0x3390, 169}, + {0x338C, 0xA777}, + {0x3390, 186}, + {0x338C, 0xA778}, + {0x3390, 199}, + {0x338C, 0xA779}, + {0x3390, 210}, + {0x338C, 0xA77A}, + {0x3390, 220}, + {0x338C, 0xA77B}, + {0x3390, 228}, + {0x338C, 0xA77C}, + {0x3390, 234}, + {0x338C, 0xA77D}, + {0x3390, 240}, + {0x338C, 0xA77E}, + {0x3390, 244}, + {0x338C, 0xA77F}, + {0x3390, 248}, + {0x338C, 0xA780}, + {0x3390, 252}, + {0x338C, 0xA781}, + {0x3390, 255}, + {0x338C, 0xA782}, + {0x3390, 0}, + {0x338C, 0xA783}, + {0x3390, 21}, + {0x338C, 0xA784}, + {0x3390, 37}, + {0x338C, 0xA785}, + {0x3390, 63}, + {0x338C, 0xA786}, + {0x3390, 100}, + {0x338C, 0xA787}, + {0x3390, 128}, + {0x338C, 0xA788}, + {0x3390, 151}, + {0x338C, 0xA789}, + {0x3390, 169}, + {0x338C, 0xA78A}, + {0x3390, 186}, + {0x338C, 0xA78B}, + {0x3390, 199}, + {0x338C, 0xA78C}, + {0x3390, 210}, + {0x338C, 0xA78D}, + {0x3390, 220}, + {0x338C, 0xA78E}, + {0x3390, 228}, + {0x338C, 0xA78F}, + {0x3390, 234}, + {0x338C, 0xA790}, + {0x3390, 240}, + {0x338C, 0xA791}, + {0x3390, 244}, + {0x338C, 0xA793}, + {0x3390, 252}, + {0x338C, 0xA794}, + {0x3390, 255}, + {0x338C, 0xA103}, + {0x3390, 6}, +}; + +static const struct mt9d112_i2c_reg_conf const lens_roll_off_tbl[] = { + { 0x34CE, 0x81A0, WORD_LEN, 0 }, + { 0x34D0, 0x6331, WORD_LEN, 0 }, + { 0x34D2, 0x3394, WORD_LEN, 0 }, + { 0x34D4, 0x9966, WORD_LEN, 0 }, + { 0x34D6, 0x4B25, WORD_LEN, 0 }, + { 0x34D8, 0x2670, WORD_LEN, 0 }, + { 0x34DA, 0x724C, WORD_LEN, 0 }, + { 0x34DC, 0xFFFD, WORD_LEN, 0 }, + { 0x34DE, 0x00CA, WORD_LEN, 0 }, + { 0x34E6, 0x00AC, WORD_LEN, 0 }, + { 0x34EE, 0x0EE1, WORD_LEN, 0 }, + { 0x34F6, 0x0D87, WORD_LEN, 0 }, + { 0x3500, 0xE1F7, WORD_LEN, 0 }, + { 0x3508, 0x1CF4, WORD_LEN, 0 }, + { 0x3510, 0x1D28, WORD_LEN, 0 }, + { 0x3518, 0x1F26, WORD_LEN, 0 }, + { 0x3520, 0x2220, WORD_LEN, 0 }, + { 0x3528, 0x333D, WORD_LEN, 0 }, + { 0x3530, 0x15D9, WORD_LEN, 0 }, + { 0x3538, 0xCFB8, WORD_LEN, 0 }, + { 0x354C, 0x05FE, WORD_LEN, 0 }, + { 0x3544, 0x05F8, WORD_LEN, 0 }, + { 0x355C, 0x0596, WORD_LEN, 0 }, + { 0x3554, 0x0611, WORD_LEN, 0 }, + { 0x34E0, 0x00F2, WORD_LEN, 0 }, + { 0x34E8, 0x00A8, WORD_LEN, 0 }, + { 0x34F0, 0x0F7B, WORD_LEN, 0 }, + { 0x34F8, 0x0CD7, WORD_LEN, 0 }, + { 0x3502, 0xFEDB, WORD_LEN, 0 }, + { 0x350A, 0x13E4, WORD_LEN, 0 }, + { 0x3512, 0x1F2C, WORD_LEN, 0 }, + { 0x351A, 0x1D20, WORD_LEN, 0 }, + { 0x3522, 0x2422, WORD_LEN, 0 }, + { 0x352A, 0x2925, WORD_LEN, 0 }, + { 0x3532, 0x1D04, WORD_LEN, 0 }, + { 0x353A, 0xFBF2, WORD_LEN, 0 }, + { 0x354E, 0x0616, WORD_LEN, 0 }, + { 0x3546, 0x0597, WORD_LEN, 0 }, + { 0x355E, 0x05CD, WORD_LEN, 0 }, + { 0x3556, 0x0529, WORD_LEN, 0 }, + { 0x34E4, 0x00B2, WORD_LEN, 0 }, + { 0x34EC, 0x005E, WORD_LEN, 0 }, + { 0x34F4, 0x0F43, WORD_LEN, 0 }, + { 0x34FC, 0x0E2F, WORD_LEN, 0 }, + { 0x3506, 0xF9FC, WORD_LEN, 0 }, + { 0x350E, 0x0CE4, WORD_LEN, 0 }, + { 0x3516, 0x1E1E, WORD_LEN, 0 }, + { 0x351E, 0x1B19, WORD_LEN, 0 }, + { 0x3526, 0x151B, WORD_LEN, 0 }, + { 0x352E, 0x1416, WORD_LEN, 0 }, + { 0x3536, 0x10FC, WORD_LEN, 0 }, + { 0x353E, 0xC018, WORD_LEN, 0 }, + { 0x3552, 0x06B4, WORD_LEN, 0 }, + { 0x354A, 0x0506, WORD_LEN, 0 }, + { 0x3562, 0x06AB, WORD_LEN, 0 }, + { 0x355A, 0x063A, WORD_LEN, 0 }, + { 0x34E2, 0x00E5, WORD_LEN, 0 }, + { 0x34EA, 0x008B, WORD_LEN, 0 }, + { 0x34F2, 0x0E4C, WORD_LEN, 0 }, + { 0x34FA, 0x0CA3, WORD_LEN, 0 }, + { 0x3504, 0x0907, WORD_LEN, 0 }, + { 0x350C, 0x1DFD, WORD_LEN, 0 }, + { 0x3514, 0x1E24, WORD_LEN, 0 }, + { 0x351C, 0x2529, WORD_LEN, 0 }, + { 0x3524, 0x1D20, WORD_LEN, 0 }, + { 0x352C, 0x2332, WORD_LEN, 0 }, + { 0x3534, 0x10E9, WORD_LEN, 0 }, + { 0x353C, 0x0BCB, WORD_LEN, 0 }, + { 0x3550, 0x04EF, WORD_LEN, 0 }, + { 0x3548, 0x0609, WORD_LEN, 0 }, + { 0x3560, 0x0580, WORD_LEN, 0 }, + { 0x3558, 0x05DD, WORD_LEN, 0 }, + { 0x3540, 0x0000, WORD_LEN, 0 }, + { 0x3542, 0x0000, WORD_LEN, 0 } +}; + +static const struct mt9d112_i2c_reg_conf const pll_setup_tbl[] = { + { 0x341E, 0x8F09, WORD_LEN, 0 }, + { 0x341C, 0x0250, WORD_LEN, 0 }, + { 0x341E, 0x8F09, WORD_LEN, 5 }, + { 0x341E, 0x8F08, WORD_LEN, 0 } +}; + +/* Refresh Sequencer */ +static const struct mt9d112_i2c_reg_conf const sequencer_tbl[] = { + { 0x338C, 0x2799, WORD_LEN, 0}, + { 0x3390, 0x6440, WORD_LEN, 5}, + { 0x338C, 0x279B, WORD_LEN, 0}, + { 0x3390, 0x6440, WORD_LEN, 5}, + { 0x338C, 0xA103, WORD_LEN, 0}, + { 0x3390, 0x0005, WORD_LEN, 5}, + { 0x338C, 0xA103, WORD_LEN, 0}, + { 0x3390, 0x0006, WORD_LEN, 5} +}; + +struct mt9d112_reg mt9d112_regs = { + .prev_snap_reg_settings = &preview_snapshot_mode_reg_settings_array[0], + .prev_snap_reg_settings_size = ARRAY_SIZE(preview_snapshot_mode_reg_settings_array), + .noise_reduction_reg_settings = &noise_reduction_reg_settings_array[0], + .noise_reduction_reg_settings_size = ARRAY_SIZE(noise_reduction_reg_settings_array), + .plltbl = pll_setup_tbl, + .plltbl_size = ARRAY_SIZE(pll_setup_tbl), + .stbl = sequencer_tbl, + .stbl_size = ARRAY_SIZE(sequencer_tbl), + .rftbl = lens_roll_off_tbl, + .rftbl_size = ARRAY_SIZE(lens_roll_off_tbl) +}; + + + diff --git a/trunk/drivers/staging/dream/camera/mt9p012.h b/trunk/drivers/staging/dream/camera/mt9p012.h new file mode 100644 index 000000000000..678a0027d42e --- /dev/null +++ b/trunk/drivers/staging/dream/camera/mt9p012.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ + + +#ifndef MT9T012_H +#define MT9T012_H + +#include + +struct reg_struct { + uint16_t vt_pix_clk_div; /* 0x0300 */ + uint16_t vt_sys_clk_div; /* 0x0302 */ + uint16_t pre_pll_clk_div; /* 0x0304 */ + uint16_t pll_multiplier; /* 0x0306 */ + uint16_t op_pix_clk_div; /* 0x0308 */ + uint16_t op_sys_clk_div; /* 0x030A */ + uint16_t scale_m; /* 0x0404 */ + uint16_t row_speed; /* 0x3016 */ + uint16_t x_addr_start; /* 0x3004 */ + uint16_t x_addr_end; /* 0x3008 */ + uint16_t y_addr_start; /* 0x3002 */ + uint16_t y_addr_end; /* 0x3006 */ + uint16_t read_mode; /* 0x3040 */ + uint16_t x_output_size ; /* 0x034C */ + uint16_t y_output_size; /* 0x034E */ + uint16_t line_length_pck; /* 0x300C */ + uint16_t frame_length_lines; /* 0x300A */ + uint16_t coarse_int_time; /* 0x3012 */ + uint16_t fine_int_time; /* 0x3014 */ +}; + + +struct mt9p012_i2c_reg_conf { + unsigned short waddr; + unsigned short wdata; +}; + + +struct mt9p012_reg { + struct reg_struct *reg_pat; + uint16_t reg_pat_size; + struct mt9p012_i2c_reg_conf *ttbl; + uint16_t ttbl_size; + struct mt9p012_i2c_reg_conf *lctbl; + uint16_t lctbl_size; + struct mt9p012_i2c_reg_conf *rftbl; + uint16_t rftbl_size; +}; + +#endif /* MT9T012_H */ diff --git a/trunk/drivers/staging/dream/camera/mt9p012_fox.c b/trunk/drivers/staging/dream/camera/mt9p012_fox.c new file mode 100644 index 000000000000..791bd6c40615 --- /dev/null +++ b/trunk/drivers/staging/dream/camera/mt9p012_fox.c @@ -0,0 +1,1306 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mt9p012.h" + +/*============================================================= + SENSOR REGISTER DEFINES +==============================================================*/ +#define MT9P012_REG_MODEL_ID 0x0000 +#define MT9P012_MODEL_ID 0x2801 +#define REG_GROUPED_PARAMETER_HOLD 0x0104 +#define GROUPED_PARAMETER_HOLD 0x0100 +#define GROUPED_PARAMETER_UPDATE 0x0000 +#define REG_COARSE_INT_TIME 0x3012 +#define REG_VT_PIX_CLK_DIV 0x0300 +#define REG_VT_SYS_CLK_DIV 0x0302 +#define REG_PRE_PLL_CLK_DIV 0x0304 +#define REG_PLL_MULTIPLIER 0x0306 +#define REG_OP_PIX_CLK_DIV 0x0308 +#define REG_OP_SYS_CLK_DIV 0x030A +#define REG_SCALE_M 0x0404 +#define REG_FRAME_LENGTH_LINES 0x300A +#define REG_LINE_LENGTH_PCK 0x300C +#define REG_X_ADDR_START 0x3004 +#define REG_Y_ADDR_START 0x3002 +#define REG_X_ADDR_END 0x3008 +#define REG_Y_ADDR_END 0x3006 +#define REG_X_OUTPUT_SIZE 0x034C +#define REG_Y_OUTPUT_SIZE 0x034E +#define REG_FINE_INTEGRATION_TIME 0x3014 +#define REG_ROW_SPEED 0x3016 +#define MT9P012_REG_RESET_REGISTER 0x301A +#define MT9P012_RESET_REGISTER_PWON 0x10CC +#define MT9P012_RESET_REGISTER_PWOFF 0x10C8 +#define REG_READ_MODE 0x3040 +#define REG_GLOBAL_GAIN 0x305E +#define REG_TEST_PATTERN_MODE 0x3070 + +#define MT9P012_REV_7 + + +enum mt9p012_test_mode { + TEST_OFF, + TEST_1, + TEST_2, + TEST_3 +}; + +enum mt9p012_resolution { + QTR_SIZE, + FULL_SIZE, + INVALID_SIZE +}; + +enum mt9p012_reg_update { + /* Sensor egisters that need to be updated during initialization */ + REG_INIT, + /* Sensor egisters that needs periodic I2C writes */ + UPDATE_PERIODIC, + /* All the sensor Registers will be updated */ + UPDATE_ALL, + /* Not valid update */ + UPDATE_INVALID +}; + +enum mt9p012_setting { + RES_PREVIEW, + RES_CAPTURE +}; + +/* actuator's Slave Address */ +#define MT9P012_AF_I2C_ADDR 0x18 + +/* AF Total steps parameters */ +#define MT9P012_STEPS_NEAR_TO_CLOSEST_INF 32 +#define MT9P012_TOTAL_STEPS_NEAR_TO_FAR 32 + +#define MT9P012_MU5M0_PREVIEW_DUMMY_PIXELS 0 +#define MT9P012_MU5M0_PREVIEW_DUMMY_LINES 0 + +/* Time in milisecs for waiting for the sensor to reset.*/ +#define MT9P012_RESET_DELAY_MSECS 66 + +/* for 20 fps preview */ +#define MT9P012_DEFAULT_CLOCK_RATE 24000000 +#define MT9P012_DEFAULT_MAX_FPS 26 /* ???? */ + +struct mt9p012_work { + struct work_struct work; +}; +static struct mt9p012_work *mt9p012_sensorw; +static struct i2c_client *mt9p012_client; + +struct mt9p012_ctrl { + const struct msm_camera_sensor_info *sensordata; + + int sensormode; + uint32_t fps_divider; /* init to 1 * 0x00000400 */ + uint32_t pict_fps_divider; /* init to 1 * 0x00000400 */ + + uint16_t curr_lens_pos; + uint16_t init_curr_lens_pos; + uint16_t my_reg_gain; + uint32_t my_reg_line_count; + + enum mt9p012_resolution prev_res; + enum mt9p012_resolution pict_res; + enum mt9p012_resolution curr_res; + enum mt9p012_test_mode set_test; +}; + + +static struct mt9p012_ctrl *mt9p012_ctrl; +static DECLARE_WAIT_QUEUE_HEAD(mt9p012_wait_queue); +DECLARE_MUTEX(mt9p012_sem); + +/*============================================================= + EXTERNAL DECLARATIONS +==============================================================*/ +extern struct mt9p012_reg mt9p012_regs; /* from mt9p012_reg.c */ + + + +/*=============================================================*/ + +static int mt9p012_i2c_rxdata(unsigned short saddr, unsigned char *rxdata, + int length) +{ + struct i2c_msg msgs[] = { + { + .addr = saddr, + .flags = 0, + .len = 2, + .buf = rxdata, + }, + { + .addr = saddr, + .flags = I2C_M_RD, + .len = length, + .buf = rxdata, + }, + }; + + if (i2c_transfer(mt9p012_client->adapter, msgs, 2) < 0) { + CDBG("mt9p012_i2c_rxdata failed!\n"); + return -EIO; + } + + return 0; +} + +static int32_t mt9p012_i2c_read_w(unsigned short saddr, unsigned short raddr, + unsigned short *rdata) +{ + int32_t rc = 0; + unsigned char buf[4]; + + if (!rdata) + return -EIO; + + memset(buf, 0, sizeof(buf)); + + buf[0] = (raddr & 0xFF00)>>8; + buf[1] = (raddr & 0x00FF); + + rc = mt9p012_i2c_rxdata(saddr, buf, 2); + if (rc < 0) + return rc; + + *rdata = buf[0] << 8 | buf[1]; + + if (rc < 0) + CDBG("mt9p012_i2c_read failed!\n"); + + return rc; +} + +static int32_t mt9p012_i2c_txdata(unsigned short saddr, unsigned char *txdata, + int length) +{ + struct i2c_msg msg[] = { + { + .addr = saddr, + .flags = 0, + .len = length, + .buf = txdata, + }, + }; + + if (i2c_transfer(mt9p012_client->adapter, msg, 1) < 0) { + CDBG("mt9p012_i2c_txdata failed\n"); + return -EIO; + } + + return 0; +} + +static int32_t mt9p012_i2c_write_b(unsigned short saddr, unsigned short baddr, + unsigned short bdata) +{ + int32_t rc = -EIO; + unsigned char buf[2]; + + memset(buf, 0, sizeof(buf)); + buf[0] = baddr; + buf[1] = bdata; + rc = mt9p012_i2c_txdata(saddr, buf, 2); + + if (rc < 0) + CDBG("i2c_write failed, saddr = 0x%x addr = 0x%x, val =0x%x!\n", + saddr, baddr, bdata); + + return rc; +} + +static int32_t mt9p012_i2c_write_w(unsigned short saddr, unsigned short waddr, + unsigned short wdata) +{ + int32_t rc = -EIO; + unsigned char buf[4]; + + memset(buf, 0, sizeof(buf)); + buf[0] = (waddr & 0xFF00)>>8; + buf[1] = (waddr & 0x00FF); + buf[2] = (wdata & 0xFF00)>>8; + buf[3] = (wdata & 0x00FF); + + rc = mt9p012_i2c_txdata(saddr, buf, 4); + + if (rc < 0) + CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n", + waddr, wdata); + + return rc; +} + +static int32_t mt9p012_i2c_write_w_table( + struct mt9p012_i2c_reg_conf *reg_conf_tbl, int num) +{ + int i; + int32_t rc = -EIO; + + for (i = 0; i < num; i++) { + rc = mt9p012_i2c_write_w(mt9p012_client->addr, + reg_conf_tbl->waddr, reg_conf_tbl->wdata); + if (rc < 0) + break; + reg_conf_tbl++; + } + + return rc; +} + +static int32_t mt9p012_test(enum mt9p012_test_mode mo) +{ + int32_t rc = 0; + + rc = mt9p012_i2c_write_w(mt9p012_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_HOLD); + if (rc < 0) + return rc; + + if (mo == TEST_OFF) + return 0; + else { + rc = mt9p012_i2c_write_w_table(mt9p012_regs.ttbl, mt9p012_regs.ttbl_size); + if (rc < 0) + return rc; + + rc = mt9p012_i2c_write_w(mt9p012_client->addr, + REG_TEST_PATTERN_MODE, (uint16_t)mo); + if (rc < 0) + return rc; + } + + rc = mt9p012_i2c_write_w(mt9p012_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_UPDATE); + if (rc < 0) + return rc; + + return rc; +} + +static int32_t mt9p012_lens_shading_enable(uint8_t is_enable) +{ + int32_t rc = 0; + + CDBG("%s: entered. enable = %d\n", __func__, is_enable); + + rc = mt9p012_i2c_write_w(mt9p012_client->addr, + REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_HOLD); + if (rc < 0) + return rc; + + rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x3780, + ((uint16_t) is_enable) << 15); + if (rc < 0) + return rc; + + rc = mt9p012_i2c_write_w(mt9p012_client->addr, + REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_UPDATE); + + CDBG("%s: exiting. rc = %d\n", __func__, rc); + return rc; +} + +static int32_t mt9p012_set_lc(void) +{ + int32_t rc; + + rc = mt9p012_i2c_write_w_table(mt9p012_regs.lctbl, mt9p012_regs.lctbl_size); + if (rc < 0) + return rc; + + rc = mt9p012_i2c_write_w_table(mt9p012_regs.rftbl, mt9p012_regs.rftbl_size); + + return rc; +} + +static void mt9p012_get_pict_fps(uint16_t fps, uint16_t *pfps) +{ + /* input fps is preview fps in Q8 format */ + uint32_t divider; /*Q10 */ + uint32_t pclk_mult; /*Q10 */ + + if (mt9p012_ctrl->prev_res == QTR_SIZE) { + divider = (uint32_t) + (((mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines * + mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck) * 0x00000400) / + (mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines * + mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck)); + + pclk_mult = + (uint32_t) ((mt9p012_regs.reg_pat[RES_CAPTURE].pll_multiplier * + 0x00000400) / (mt9p012_regs.reg_pat[RES_PREVIEW].pll_multiplier)); + } else { + /* full size resolution used for preview. */ + divider = 0x00000400; /*1.0 */ + pclk_mult = 0x00000400; /*1.0 */ + } + + /* Verify PCLK settings and frame sizes. */ + *pfps = (uint16_t) (fps * divider * pclk_mult / 0x00000400 / + 0x00000400); +} + +static uint16_t mt9p012_get_prev_lines_pf(void) +{ + if (mt9p012_ctrl->prev_res == QTR_SIZE) + return mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines; + else + return mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines; +} + +static uint16_t mt9p012_get_prev_pixels_pl(void) +{ + if (mt9p012_ctrl->prev_res == QTR_SIZE) + return mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck; + else + return mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck; +} + +static uint16_t mt9p012_get_pict_lines_pf(void) +{ + return mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines; +} + +static uint16_t mt9p012_get_pict_pixels_pl(void) +{ + return mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck; +} + +static uint32_t mt9p012_get_pict_max_exp_lc(void) +{ + uint16_t snapshot_lines_per_frame; + + if (mt9p012_ctrl->pict_res == QTR_SIZE) + snapshot_lines_per_frame = + mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines - 1; + else + snapshot_lines_per_frame = + mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines - 1; + + return snapshot_lines_per_frame * 24; +} + +static int32_t mt9p012_set_fps(struct fps_cfg *fps) +{ + /* input is new fps in Q10 format */ + int32_t rc = 0; + + mt9p012_ctrl->fps_divider = fps->fps_div; + mt9p012_ctrl->pict_fps_divider = fps->pict_fps_div; + + rc = + mt9p012_i2c_write_w(mt9p012_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_HOLD); + if (rc < 0) + return -EBUSY; + + rc = + mt9p012_i2c_write_w(mt9p012_client->addr, + REG_LINE_LENGTH_PCK, + (mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck * + fps->f_mult / 0x00000400)); + if (rc < 0) + return rc; + + rc = + mt9p012_i2c_write_w(mt9p012_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_UPDATE); + + return rc; +} + +static int32_t mt9p012_write_exp_gain(uint16_t gain, uint32_t line) +{ + uint16_t max_legal_gain = 0x01FF; + uint32_t line_length_ratio = 0x00000400; + enum mt9p012_setting setting; + int32_t rc = 0; + + CDBG("Line:%d mt9p012_write_exp_gain \n", __LINE__); + + if (mt9p012_ctrl->sensormode == SENSOR_PREVIEW_MODE) { + mt9p012_ctrl->my_reg_gain = gain; + mt9p012_ctrl->my_reg_line_count = (uint16_t)line; + } + + if (gain > max_legal_gain) { + CDBG("Max legal gain Line:%d \n", __LINE__); + gain = max_legal_gain; + } + + /* Verify no overflow */ + if (mt9p012_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) { + line = (uint32_t)(line * mt9p012_ctrl->fps_divider / + 0x00000400); + setting = RES_PREVIEW; + } else { + line = (uint32_t)(line * mt9p012_ctrl->pict_fps_divider / + 0x00000400); + setting = RES_CAPTURE; + } + + /* Set digital gain to 1 */ +#ifdef MT9P012_REV_7 + gain |= 0x1000; +#else + gain |= 0x0200; +#endif + + if ((mt9p012_regs.reg_pat[setting].frame_length_lines - 1) < line) { + line_length_ratio = (uint32_t) (line * 0x00000400) / + (mt9p012_regs.reg_pat[setting].frame_length_lines - 1); + } else + line_length_ratio = 0x00000400; + + rc = + mt9p012_i2c_write_w(mt9p012_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_HOLD); + if (rc < 0) { + CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__); + return rc; + } + + rc = + mt9p012_i2c_write_w( + mt9p012_client->addr, + REG_GLOBAL_GAIN, gain); + if (rc < 0) { + CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__); + return rc; + } + + rc = + mt9p012_i2c_write_w(mt9p012_client->addr, + REG_COARSE_INT_TIME, + line); + if (rc < 0) { + CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__); + return rc; + } + + CDBG("mt9p012_write_exp_gain: gain = %d, line = %d\n", gain, line); + + rc = + mt9p012_i2c_write_w(mt9p012_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_UPDATE); + if (rc < 0) + CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__); + + return rc; +} + +static int32_t mt9p012_set_pict_exp_gain(uint16_t gain, uint32_t line) +{ + int32_t rc = 0; + + CDBG("Line:%d mt9p012_set_pict_exp_gain \n", __LINE__); + + rc = + mt9p012_write_exp_gain(gain, line); + if (rc < 0) { + CDBG("Line:%d mt9p012_set_pict_exp_gain failed... \n", + __LINE__); + return rc; + } + + rc = + mt9p012_i2c_write_w(mt9p012_client->addr, + MT9P012_REG_RESET_REGISTER, + 0x10CC | 0x0002); + if (rc < 0) { + CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__); + return rc; + } + + mdelay(5); + + /* camera_timed_wait(snapshot_wait*exposure_ratio); */ + return rc; +} + +static int32_t mt9p012_setting(enum mt9p012_reg_update rupdate, + enum mt9p012_setting rt) +{ + int32_t rc = 0; + + switch (rupdate) { + case UPDATE_PERIODIC: + if (rt == RES_PREVIEW || rt == RES_CAPTURE) { + + struct mt9p012_i2c_reg_conf ppc_tbl[] = { + {REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_HOLD}, + {REG_ROW_SPEED, mt9p012_regs.reg_pat[rt].row_speed}, + {REG_X_ADDR_START, mt9p012_regs.reg_pat[rt].x_addr_start}, + {REG_X_ADDR_END, mt9p012_regs.reg_pat[rt].x_addr_end}, + {REG_Y_ADDR_START, mt9p012_regs.reg_pat[rt].y_addr_start}, + {REG_Y_ADDR_END, mt9p012_regs.reg_pat[rt].y_addr_end}, + {REG_READ_MODE, mt9p012_regs.reg_pat[rt].read_mode}, + {REG_SCALE_M, mt9p012_regs.reg_pat[rt].scale_m}, + {REG_X_OUTPUT_SIZE, mt9p012_regs.reg_pat[rt].x_output_size}, + {REG_Y_OUTPUT_SIZE, mt9p012_regs.reg_pat[rt].y_output_size}, + + {REG_LINE_LENGTH_PCK, mt9p012_regs.reg_pat[rt].line_length_pck}, + {REG_FRAME_LENGTH_LINES, + (mt9p012_regs.reg_pat[rt].frame_length_lines * + mt9p012_ctrl->fps_divider / 0x00000400)}, + {REG_COARSE_INT_TIME, mt9p012_regs.reg_pat[rt].coarse_int_time}, + {REG_FINE_INTEGRATION_TIME, mt9p012_regs.reg_pat[rt].fine_int_time}, + {REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_UPDATE}, + }; + + rc = mt9p012_i2c_write_w_table(&ppc_tbl[0], + ARRAY_SIZE(ppc_tbl)); + if (rc < 0) + return rc; + + rc = mt9p012_test(mt9p012_ctrl->set_test); + if (rc < 0) + return rc; + + rc = + mt9p012_i2c_write_w(mt9p012_client->addr, + MT9P012_REG_RESET_REGISTER, + MT9P012_RESET_REGISTER_PWON | 0x0002); + if (rc < 0) + return rc; + + mdelay(5); /* 15? wait for sensor to transition*/ + + return rc; + } + break; /* UPDATE_PERIODIC */ + + case REG_INIT: + if (rt == RES_PREVIEW || rt == RES_CAPTURE) { + struct mt9p012_i2c_reg_conf ipc_tbl1[] = { + {MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWOFF}, + {REG_VT_PIX_CLK_DIV, mt9p012_regs.reg_pat[rt].vt_pix_clk_div}, + {REG_VT_SYS_CLK_DIV, mt9p012_regs.reg_pat[rt].vt_sys_clk_div}, + {REG_PRE_PLL_CLK_DIV, mt9p012_regs.reg_pat[rt].pre_pll_clk_div}, + {REG_PLL_MULTIPLIER, mt9p012_regs.reg_pat[rt].pll_multiplier}, + {REG_OP_PIX_CLK_DIV, mt9p012_regs.reg_pat[rt].op_pix_clk_div}, + {REG_OP_SYS_CLK_DIV, mt9p012_regs.reg_pat[rt].op_sys_clk_div}, +#ifdef MT9P012_REV_7 + {0x30B0, 0x0001}, + {0x308E, 0xE060}, + {0x3092, 0x0A52}, + {0x3094, 0x4656}, + {0x3096, 0x5652}, + {0x30CA, 0x8006}, + {0x312A, 0xDD02}, + {0x312C, 0x00E4}, + {0x3170, 0x299A}, +#endif + /* optimized settings for noise */ + {0x3088, 0x6FF6}, + {0x3154, 0x0282}, + {0x3156, 0x0381}, + {0x3162, 0x04CE}, + {0x0204, 0x0010}, + {0x0206, 0x0010}, + {0x0208, 0x0010}, + {0x020A, 0x0010}, + {0x020C, 0x0010}, + {MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWON}, + }; + + struct mt9p012_i2c_reg_conf ipc_tbl2[] = { + {MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWOFF}, + {REG_VT_PIX_CLK_DIV, mt9p012_regs.reg_pat[rt].vt_pix_clk_div}, + {REG_VT_SYS_CLK_DIV, mt9p012_regs.reg_pat[rt].vt_sys_clk_div}, + {REG_PRE_PLL_CLK_DIV, mt9p012_regs.reg_pat[rt].pre_pll_clk_div}, + {REG_PLL_MULTIPLIER, mt9p012_regs.reg_pat[rt].pll_multiplier}, + {REG_OP_PIX_CLK_DIV, mt9p012_regs.reg_pat[rt].op_pix_clk_div}, + {REG_OP_SYS_CLK_DIV, mt9p012_regs.reg_pat[rt].op_sys_clk_div}, +#ifdef MT9P012_REV_7 + {0x30B0, 0x0001}, + {0x308E, 0xE060}, + {0x3092, 0x0A52}, + {0x3094, 0x4656}, + {0x3096, 0x5652}, + {0x30CA, 0x8006}, + {0x312A, 0xDD02}, + {0x312C, 0x00E4}, + {0x3170, 0x299A}, +#endif + /* optimized settings for noise */ + {0x3088, 0x6FF6}, + {0x3154, 0x0282}, + {0x3156, 0x0381}, + {0x3162, 0x04CE}, + {0x0204, 0x0010}, + {0x0206, 0x0010}, + {0x0208, 0x0010}, + {0x020A, 0x0010}, + {0x020C, 0x0010}, + {MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWON}, + }; + + struct mt9p012_i2c_reg_conf ipc_tbl3[] = { + {REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_HOLD}, + /* Set preview or snapshot mode */ + {REG_ROW_SPEED, mt9p012_regs.reg_pat[rt].row_speed}, + {REG_X_ADDR_START, mt9p012_regs.reg_pat[rt].x_addr_start}, + {REG_X_ADDR_END, mt9p012_regs.reg_pat[rt].x_addr_end}, + {REG_Y_ADDR_START, mt9p012_regs.reg_pat[rt].y_addr_start}, + {REG_Y_ADDR_END, mt9p012_regs.reg_pat[rt].y_addr_end}, + {REG_READ_MODE, mt9p012_regs.reg_pat[rt].read_mode}, + {REG_SCALE_M, mt9p012_regs.reg_pat[rt].scale_m}, + {REG_X_OUTPUT_SIZE, mt9p012_regs.reg_pat[rt].x_output_size}, + {REG_Y_OUTPUT_SIZE, mt9p012_regs.reg_pat[rt].y_output_size}, + {REG_LINE_LENGTH_PCK, mt9p012_regs.reg_pat[rt].line_length_pck}, + {REG_FRAME_LENGTH_LINES, + mt9p012_regs.reg_pat[rt].frame_length_lines}, + {REG_COARSE_INT_TIME, mt9p012_regs.reg_pat[rt].coarse_int_time}, + {REG_FINE_INTEGRATION_TIME, mt9p012_regs.reg_pat[rt].fine_int_time}, + {REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_UPDATE}, + }; + + /* reset fps_divider */ + mt9p012_ctrl->fps_divider = 1 * 0x0400; + + rc = mt9p012_i2c_write_w_table(&ipc_tbl1[0], + ARRAY_SIZE(ipc_tbl1)); + if (rc < 0) + return rc; + + rc = mt9p012_i2c_write_w_table(&ipc_tbl2[0], + ARRAY_SIZE(ipc_tbl2)); + if (rc < 0) + return rc; + + mdelay(5); + + rc = mt9p012_i2c_write_w_table(&ipc_tbl3[0], + ARRAY_SIZE(ipc_tbl3)); + if (rc < 0) + return rc; + + /* load lens shading */ + rc = mt9p012_i2c_write_w(mt9p012_client->addr, + REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_HOLD); + if (rc < 0) + return rc; + + rc = mt9p012_set_lc(); + if (rc < 0) + return rc; + + rc = mt9p012_i2c_write_w(mt9p012_client->addr, + REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_UPDATE); + + if (rc < 0) + return rc; + } + break; /* case REG_INIT: */ + + default: + rc = -EINVAL; + break; + } /* switch (rupdate) */ + + return rc; +} + +static int32_t mt9p012_video_config(int mode, int res) +{ + int32_t rc; + + switch (res) { + case QTR_SIZE: + rc = mt9p012_setting(UPDATE_PERIODIC, RES_PREVIEW); + if (rc < 0) + return rc; + + CDBG("mt9p012 sensor configuration done!\n"); + break; + + case FULL_SIZE: + rc = + mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE); + if (rc < 0) + return rc; + + break; + + default: + return 0; + } /* switch */ + + mt9p012_ctrl->prev_res = res; + mt9p012_ctrl->curr_res = res; + mt9p012_ctrl->sensormode = mode; + + rc = + mt9p012_write_exp_gain(mt9p012_ctrl->my_reg_gain, + mt9p012_ctrl->my_reg_line_count); + + rc = + mt9p012_i2c_write_w(mt9p012_client->addr, + MT9P012_REG_RESET_REGISTER, + 0x10cc|0x0002); + + return rc; +} + +static int32_t mt9p012_snapshot_config(int mode) +{ + int32_t rc = 0; + + rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE); + if (rc < 0) + return rc; + + mt9p012_ctrl->curr_res = mt9p012_ctrl->pict_res; + + mt9p012_ctrl->sensormode = mode; + + return rc; +} + +static int32_t mt9p012_raw_snapshot_config(int mode) +{ + int32_t rc = 0; + + rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE); + if (rc < 0) + return rc; + + mt9p012_ctrl->curr_res = mt9p012_ctrl->pict_res; + + mt9p012_ctrl->sensormode = mode; + + return rc; +} + +static int32_t mt9p012_power_down(void) +{ + int32_t rc = 0; + + rc = mt9p012_i2c_write_w(mt9p012_client->addr, + MT9P012_REG_RESET_REGISTER, + MT9P012_RESET_REGISTER_PWOFF); + + mdelay(5); + return rc; +} + +static int32_t mt9p012_move_focus(int direction, int32_t num_steps) +{ + int16_t step_direction; + int16_t actual_step; + int16_t next_position; + uint8_t code_val_msb, code_val_lsb; + + if (num_steps > MT9P012_TOTAL_STEPS_NEAR_TO_FAR) + num_steps = MT9P012_TOTAL_STEPS_NEAR_TO_FAR; + else if (num_steps == 0) { + CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__); + return -EINVAL; + } + + if (direction == MOVE_NEAR) + step_direction = 16; /* 10bit */ + else if (direction == MOVE_FAR) + step_direction = -16; /* 10 bit */ + else { + CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__); + return -EINVAL; + } + + if (mt9p012_ctrl->curr_lens_pos < mt9p012_ctrl->init_curr_lens_pos) + mt9p012_ctrl->curr_lens_pos = + mt9p012_ctrl->init_curr_lens_pos; + + actual_step = (int16_t)(step_direction * (int16_t)num_steps); + next_position = (int16_t)(mt9p012_ctrl->curr_lens_pos + actual_step); + + if (next_position > 1023) + next_position = 1023; + else if (next_position < 0) + next_position = 0; + + code_val_msb = next_position >> 4; + code_val_lsb = (next_position & 0x000F) << 4; + /* code_val_lsb |= mode_mask; */ + + /* Writing the digital code for current to the actuator */ + if (mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, + code_val_msb, code_val_lsb) < 0) { + CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__); + return -EBUSY; + } + + /* Storing the current lens Position */ + mt9p012_ctrl->curr_lens_pos = next_position; + + return 0; +} + +static int32_t mt9p012_set_default_focus(void) +{ + int32_t rc = 0; + uint8_t code_val_msb, code_val_lsb; + + code_val_msb = 0x00; + code_val_lsb = 0x00; + + /* Write the digital code for current to the actuator */ + rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1, + code_val_msb, code_val_lsb); + + mt9p012_ctrl->curr_lens_pos = 0; + mt9p012_ctrl->init_curr_lens_pos = 0; + + return rc; +} + +static int mt9p012_probe_init_done(const struct msm_camera_sensor_info *data) +{ + gpio_direction_output(data->sensor_reset, 0); + gpio_free(data->sensor_reset); + return 0; +} + +static int mt9p012_probe_init_sensor(const struct msm_camera_sensor_info *data) +{ + int32_t rc; + uint16_t chipid; + + rc = gpio_request(data->sensor_reset, "mt9p012"); + if (!rc) + gpio_direction_output(data->sensor_reset, 1); + else + goto init_probe_done; + + mdelay(20); + + /* RESET the sensor image part via I2C command */ + CDBG("mt9p012_sensor_init(): reseting sensor.\n"); + rc = mt9p012_i2c_write_w(mt9p012_client->addr, + MT9P012_REG_RESET_REGISTER, 0x10CC|0x0001); + if (rc < 0) { + CDBG("sensor reset failed. rc = %d\n", rc); + goto init_probe_fail; + } + + mdelay(MT9P012_RESET_DELAY_MSECS); + + /* 3. Read sensor Model ID: */ + rc = mt9p012_i2c_read_w(mt9p012_client->addr, + MT9P012_REG_MODEL_ID, &chipid); + if (rc < 0) + goto init_probe_fail; + + /* 4. Compare sensor ID to MT9T012VC ID: */ + if (chipid != MT9P012_MODEL_ID) { + CDBG("mt9p012 wrong model_id = 0x%x\n", chipid); + rc = -ENODEV; + goto init_probe_fail; + } + + rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x306E, 0x9000); + if (rc < 0) { + CDBG("REV_7 write failed. rc = %d\n", rc); + goto init_probe_fail; + } + + /* RESET_REGISTER, enable parallel interface and disable serialiser */ + CDBG("mt9p012_sensor_init(): enabling parallel interface.\n"); + rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x301A, 0x10CC); + if (rc < 0) { + CDBG("enable parallel interface failed. rc = %d\n", rc); + goto init_probe_fail; + } + + /* To disable the 2 extra lines */ + rc = mt9p012_i2c_write_w(mt9p012_client->addr, + 0x3064, 0x0805); + + if (rc < 0) { + CDBG("disable the 2 extra lines failed. rc = %d\n", rc); + goto init_probe_fail; + } + + mdelay(MT9P012_RESET_DELAY_MSECS); + goto init_probe_done; + +init_probe_fail: + mt9p012_probe_init_done(data); +init_probe_done: + return rc; +} + +static int mt9p012_sensor_open_init(const struct msm_camera_sensor_info *data) +{ + int32_t rc; + + mt9p012_ctrl = kzalloc(sizeof(struct mt9p012_ctrl), GFP_KERNEL); + if (!mt9p012_ctrl) { + CDBG("mt9p012_init failed!\n"); + rc = -ENOMEM; + goto init_done; + } + + mt9p012_ctrl->fps_divider = 1 * 0x00000400; + mt9p012_ctrl->pict_fps_divider = 1 * 0x00000400; + mt9p012_ctrl->set_test = TEST_OFF; + mt9p012_ctrl->prev_res = QTR_SIZE; + mt9p012_ctrl->pict_res = FULL_SIZE; + + if (data) + mt9p012_ctrl->sensordata = data; + + /* enable mclk first */ + msm_camio_clk_rate_set(MT9P012_DEFAULT_CLOCK_RATE); + mdelay(20); + + msm_camio_camif_pad_reg_reset(); + mdelay(20); + + rc = mt9p012_probe_init_sensor(data); + if (rc < 0) + goto init_fail1; + + if (mt9p012_ctrl->prev_res == QTR_SIZE) + rc = mt9p012_setting(REG_INIT, RES_PREVIEW); + else + rc = mt9p012_setting(REG_INIT, RES_CAPTURE); + + if (rc < 0) { + CDBG("mt9p012_setting failed. rc = %d\n", rc); + goto init_fail1; + } + + /* sensor : output enable */ + CDBG("mt9p012_sensor_open_init(): enabling output.\n"); + rc = mt9p012_i2c_write_w(mt9p012_client->addr, + MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWON); + if (rc < 0) { + CDBG("sensor output enable failed. rc = %d\n", rc); + goto init_fail1; + } + + /* TODO: enable AF actuator */ +#if 0 + CDBG("enable AF actuator, gpio = %d\n", + mt9p012_ctrl->sensordata->vcm_pwd); + rc = gpio_request(mt9p012_ctrl->sensordata->vcm_pwd, "mt9p012"); + if (!rc) + gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 1); + else { + CDBG("mt9p012_ctrl gpio request failed!\n"); + goto init_fail1; + } + mdelay(20); + + rc = mt9p012_set_default_focus(); +#endif + if (rc >= 0) + goto init_done; + + /* TODO: + * gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 0); + * gpio_free(mt9p012_ctrl->sensordata->vcm_pwd); */ +init_fail1: + mt9p012_probe_init_done(data); + kfree(mt9p012_ctrl); +init_done: + return rc; +} + +static int mt9p012_init_client(struct i2c_client *client) +{ + /* Initialize the MSM_CAMI2C Chip */ + init_waitqueue_head(&mt9p012_wait_queue); + return 0; +} + +static int32_t mt9p012_set_sensor_mode(int mode, int res) +{ + int32_t rc = 0; + + switch (mode) { + case SENSOR_PREVIEW_MODE: + rc = mt9p012_video_config(mode, res); + break; + + case SENSOR_SNAPSHOT_MODE: + rc = mt9p012_snapshot_config(mode); + break; + + case SENSOR_RAW_SNAPSHOT_MODE: + rc = mt9p012_raw_snapshot_config(mode); + break; + + default: + rc = -EINVAL; + break; + } + + return rc; +} + +int mt9p012_sensor_config(void __user *argp) +{ + struct sensor_cfg_data cdata; + int rc = 0; + + if (copy_from_user(&cdata, + (void *)argp, + sizeof(struct sensor_cfg_data))) + return -EFAULT; + + down(&mt9p012_sem); + + CDBG("%s: cfgtype = %d\n", __func__, cdata.cfgtype); + switch (cdata.cfgtype) { + case CFG_GET_PICT_FPS: + mt9p012_get_pict_fps(cdata.cfg.gfps.prevfps, + &(cdata.cfg.gfps.pictfps)); + + if (copy_to_user((void *)argp, &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_GET_PREV_L_PF: + cdata.cfg.prevl_pf = mt9p012_get_prev_lines_pf(); + + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_GET_PREV_P_PL: + cdata.cfg.prevp_pl = mt9p012_get_prev_pixels_pl(); + + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_GET_PICT_L_PF: + cdata.cfg.pictl_pf = mt9p012_get_pict_lines_pf(); + + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_GET_PICT_P_PL: + cdata.cfg.pictp_pl = mt9p012_get_pict_pixels_pl(); + + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_GET_PICT_MAX_EXP_LC: + cdata.cfg.pict_max_exp_lc = + mt9p012_get_pict_max_exp_lc(); + + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_SET_FPS: + case CFG_SET_PICT_FPS: + rc = mt9p012_set_fps(&(cdata.cfg.fps)); + break; + + case CFG_SET_EXP_GAIN: + rc = mt9p012_write_exp_gain(cdata.cfg.exp_gain.gain, + cdata.cfg.exp_gain.line); + break; + + case CFG_SET_PICT_EXP_GAIN: + CDBG("Line:%d CFG_SET_PICT_EXP_GAIN \n", __LINE__); + rc = mt9p012_set_pict_exp_gain(cdata.cfg.exp_gain.gain, + cdata.cfg.exp_gain.line); + break; + + case CFG_SET_MODE: + rc = mt9p012_set_sensor_mode(cdata.mode, cdata.rs); + break; + + case CFG_PWR_DOWN: + rc = mt9p012_power_down(); + break; + + case CFG_MOVE_FOCUS: + CDBG("mt9p012_ioctl: CFG_MOVE_FOCUS: cdata.cfg.focus.dir=%d cdata.cfg.focus.steps=%d\n", + cdata.cfg.focus.dir, cdata.cfg.focus.steps); + rc = mt9p012_move_focus(cdata.cfg.focus.dir, + cdata.cfg.focus.steps); + break; + + case CFG_SET_DEFAULT_FOCUS: + rc = mt9p012_set_default_focus(); + break; + + case CFG_SET_LENS_SHADING: + CDBG("%s: CFG_SET_LENS_SHADING\n", __func__); + rc = mt9p012_lens_shading_enable(cdata.cfg.lens_shading); + break; + + case CFG_GET_AF_MAX_STEPS: + cdata.max_steps = MT9P012_STEPS_NEAR_TO_CLOSEST_INF; + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_SET_EFFECT: + default: + rc = -EINVAL; + break; + } + + up(&mt9p012_sem); + return rc; +} + +int mt9p012_sensor_release(void) +{ + int rc = -EBADF; + + down(&mt9p012_sem); + + mt9p012_power_down(); + + gpio_direction_output(mt9p012_ctrl->sensordata->sensor_reset, + 0); + gpio_free(mt9p012_ctrl->sensordata->sensor_reset); + + gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 0); + gpio_free(mt9p012_ctrl->sensordata->vcm_pwd); + + kfree(mt9p012_ctrl); + mt9p012_ctrl = NULL; + + CDBG("mt9p012_release completed\n"); + + up(&mt9p012_sem); + return rc; +} + +static int mt9p012_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int rc = 0; + CDBG("mt9p012_probe called!\n"); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + CDBG("i2c_check_functionality failed\n"); + goto probe_failure; + } + + mt9p012_sensorw = kzalloc(sizeof(struct mt9p012_work), GFP_KERNEL); + if (!mt9p012_sensorw) { + CDBG("kzalloc failed.\n"); + rc = -ENOMEM; + goto probe_failure; + } + + i2c_set_clientdata(client, mt9p012_sensorw); + mt9p012_init_client(client); + mt9p012_client = client; + + mdelay(50); + + CDBG("mt9p012_probe successed! rc = %d\n", rc); + return 0; + +probe_failure: + CDBG("mt9p012_probe failed! rc = %d\n", rc); + return rc; +} + +static const struct i2c_device_id mt9p012_i2c_id[] = { + { "mt9p012", 0}, + { } +}; + +static struct i2c_driver mt9p012_i2c_driver = { + .id_table = mt9p012_i2c_id, + .probe = mt9p012_i2c_probe, + .remove = __exit_p(mt9p012_i2c_remove), + .driver = { + .name = "mt9p012", + }, +}; + +static int mt9p012_sensor_probe(const struct msm_camera_sensor_info *info, + struct msm_sensor_ctrl *s) +{ + int rc = i2c_add_driver(&mt9p012_i2c_driver); + if (rc < 0 || mt9p012_client == NULL) { + rc = -ENOTSUPP; + goto probe_done; + } + + msm_camio_clk_rate_set(MT9P012_DEFAULT_CLOCK_RATE); + mdelay(20); + + rc = mt9p012_probe_init_sensor(info); + if (rc < 0) + goto probe_done; + + s->s_init = mt9p012_sensor_open_init; + s->s_release = mt9p012_sensor_release; + s->s_config = mt9p012_sensor_config; + mt9p012_probe_init_done(info); + +probe_done: + CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__); + return rc; +} + +static int __mt9p012_probe(struct platform_device *pdev) +{ + return msm_camera_drv_start(pdev, mt9p012_sensor_probe); +} + +static struct platform_driver msm_camera_driver = { + .probe = __mt9p012_probe, + .driver = { + .name = "msm_camera_mt9p012", + .owner = THIS_MODULE, + }, +}; + +static int __init mt9p012_init(void) +{ + return platform_driver_register(&msm_camera_driver); +} + +module_init(mt9p012_init); diff --git a/trunk/drivers/staging/dream/camera/mt9p012_reg.c b/trunk/drivers/staging/dream/camera/mt9p012_reg.c new file mode 100644 index 000000000000..e5223d693b2c --- /dev/null +++ b/trunk/drivers/staging/dream/camera/mt9p012_reg.c @@ -0,0 +1,573 @@ +/* + * Copyright (C) 2009 QUALCOMM Incorporated. + */ + +#include "mt9p012.h" +#include + +/*Micron settings from Applications for lower power consumption.*/ +struct reg_struct mt9p012_reg_pat[2] = { + { /* Preview */ + /* vt_pix_clk_div REG=0x0300 */ + 6, /* 5 */ + + /* vt_sys_clk_div REG=0x0302 */ + 1, + + /* pre_pll_clk_div REG=0x0304 */ + 2, + + /* pll_multiplier REG=0x0306 */ + 60, + + /* op_pix_clk_div REG=0x0308 */ + 8, /* 10 */ + + /* op_sys_clk_div REG=0x030A */ + 1, + + /* scale_m REG=0x0404 */ + 16, + + /* row_speed REG=0x3016 */ + 0x0111, + + /* x_addr_start REG=0x3004 */ + 8, + + /* x_addr_end REG=0x3008 */ + 2597, + + /* y_addr_start REG=0x3002 */ + 8, + + /* y_addr_end REG=0x3006 */ + 1949, + + /* read_mode REG=0x3040 + * Preview 2x2 skipping */ + 0x00C3, + + /* x_output_size REG=0x034C */ + 1296, + + /* y_output_size REG=0x034E */ + 972, + + /* line_length_pck REG=0x300C */ + 3784, + + /* frame_length_lines REG=0x300A */ + 1057, + + /* coarse_integration_time REG=0x3012 */ + 16, + + /* fine_integration_time REG=0x3014 */ + 1764 + }, + { /*Snapshot*/ + /* vt_pix_clk_div REG=0x0300 */ + 6, + + /* vt_sys_clk_div REG=0x0302 */ + 1, + + /* pre_pll_clk_div REG=0x0304 */ + 2, + + /* pll_multiplier REG=0x0306 + * 60 for 10fps snapshot */ + 60, + + /* op_pix_clk_div REG=0x0308 */ + 8, + + /* op_sys_clk_div REG=0x030A */ + 1, + + /* scale_m REG=0x0404 */ + 16, + + /* row_speed REG=0x3016 */ + 0x0111, + + /* x_addr_start REG=0x3004 */ + 8, + + /* x_addr_end REG=0x3008 */ + 2615, + + /* y_addr_start REG=0x3002 */ + 8, + + /* y_addr_end REG=0x3006 */ + 1967, + + /* read_mode REG=0x3040 */ + 0x0041, + + /* x_output_size REG=0x034C */ + 2608, + + /* y_output_size REG=0x034E */ + 1960, + + /* line_length_pck REG=0x300C */ + 3911, + + /* frame_length_lines REG=0x300A //10 fps snapshot */ + 2045, + + /* coarse_integration_time REG=0x3012 */ + 16, + + /* fine_integration_time REG=0x3014 */ + 882 + } +}; + + +struct mt9p012_i2c_reg_conf mt9p012_test_tbl[] = { + {0x3044, 0x0544 & 0xFBFF}, + {0x30CA, 0x0004 | 0x0001}, + {0x30D4, 0x9020 & 0x7FFF}, + {0x31E0, 0x0003 & 0xFFFE}, + {0x3180, 0x91FF & 0x7FFF}, + {0x301A, (0x10CC | 0x8000) & 0xFFF7}, + {0x301E, 0x0000}, + {0x3780, 0x0000}, +}; + + +struct mt9p012_i2c_reg_conf mt9p012_lc_tbl[] = { + /* [Lens shading 85 Percent TL84] */ + /* P_RD_P0Q0 */ + {0x360A, 0x7FEF}, + /* P_RD_P0Q1 */ + {0x360C, 0x232C}, + /* P_RD_P0Q2 */ + {0x360E, 0x7050}, + /* P_RD_P0Q3 */ + {0x3610, 0xF3CC}, + /* P_RD_P0Q4 */ + {0x3612, 0x89D1}, + /* P_RD_P1Q0 */ + {0x364A, 0xBE0D}, + /* P_RD_P1Q1 */ + {0x364C, 0x9ACB}, + /* P_RD_P1Q2 */ + {0x364E, 0x2150}, + /* P_RD_P1Q3 */ + {0x3650, 0xB26B}, + /* P_RD_P1Q4 */ + {0x3652, 0x9511}, + /* P_RD_P2Q0 */ + {0x368A, 0x2151}, + /* P_RD_P2Q1 */ + {0x368C, 0x00AD}, + /* P_RD_P2Q2 */ + {0x368E, 0x8334}, + /* P_RD_P2Q3 */ + {0x3690, 0x478E}, + /* P_RD_P2Q4 */ + {0x3692, 0x0515}, + /* P_RD_P3Q0 */ + {0x36CA, 0x0710}, + /* P_RD_P3Q1 */ + {0x36CC, 0x452D}, + /* P_RD_P3Q2 */ + {0x36CE, 0xF352}, + /* P_RD_P3Q3 */ + {0x36D0, 0x190F}, + /* P_RD_P3Q4 */ + {0x36D2, 0x4413}, + /* P_RD_P4Q0 */ + {0x370A, 0xD112}, + /* P_RD_P4Q1 */ + {0x370C, 0xF50F}, + /* P_RD_P4Q2 */ + {0x370C, 0xF50F}, + /* P_RD_P4Q3 */ + {0x3710, 0xDC11}, + /* P_RD_P4Q4 */ + {0x3712, 0xD776}, + /* P_GR_P0Q0 */ + {0x3600, 0x1750}, + /* P_GR_P0Q1 */ + {0x3602, 0xF0AC}, + /* P_GR_P0Q2 */ + {0x3604, 0x4711}, + /* P_GR_P0Q3 */ + {0x3606, 0x07CE}, + /* P_GR_P0Q4 */ + {0x3608, 0x96B2}, + /* P_GR_P1Q0 */ + {0x3640, 0xA9AE}, + /* P_GR_P1Q1 */ + {0x3642, 0xF9AC}, + /* P_GR_P1Q2 */ + {0x3644, 0x39F1}, + /* P_GR_P1Q3 */ + {0x3646, 0x016F}, + /* P_GR_P1Q4 */ + {0x3648, 0x8AB2}, + /* P_GR_P2Q0 */ + {0x3680, 0x1752}, + /* P_GR_P2Q1 */ + {0x3682, 0x70F0}, + /* P_GR_P2Q2 */ + {0x3684, 0x83F5}, + /* P_GR_P2Q3 */ + {0x3686, 0x8392}, + /* P_GR_P2Q4 */ + {0x3688, 0x1FD6}, + /* P_GR_P3Q0 */ + {0x36C0, 0x1131}, + /* P_GR_P3Q1 */ + {0x36C2, 0x3DAF}, + /* P_GR_P3Q2 */ + {0x36C4, 0x89B4}, + /* P_GR_P3Q3 */ + {0x36C6, 0xA391}, + /* P_GR_P3Q4 */ + {0x36C8, 0x1334}, + /* P_GR_P4Q0 */ + {0x3700, 0xDC13}, + /* P_GR_P4Q1 */ + {0x3702, 0xD052}, + /* P_GR_P4Q2 */ + {0x3704, 0x5156}, + /* P_GR_P4Q3 */ + {0x3706, 0x1F13}, + /* P_GR_P4Q4 */ + {0x3708, 0x8C38}, + /* P_BL_P0Q0 */ + {0x3614, 0x0050}, + /* P_BL_P0Q1 */ + {0x3616, 0xBD4C}, + /* P_BL_P0Q2 */ + {0x3618, 0x41B0}, + /* P_BL_P0Q3 */ + {0x361A, 0x660D}, + /* P_BL_P0Q4 */ + {0x361C, 0xC590}, + /* P_BL_P1Q0 */ + {0x3654, 0x87EC}, + /* P_BL_P1Q1 */ + {0x3656, 0xE44C}, + /* P_BL_P1Q2 */ + {0x3658, 0x302E}, + /* P_BL_P1Q3 */ + {0x365A, 0x106E}, + /* P_BL_P1Q4 */ + {0x365C, 0xB58E}, + /* P_BL_P2Q0 */ + {0x3694, 0x0DD1}, + /* P_BL_P2Q1 */ + {0x3696, 0x2A50}, + /* P_BL_P2Q2 */ + {0x3698, 0xC793}, + /* P_BL_P2Q3 */ + {0x369A, 0xE8F1}, + /* P_BL_P2Q4 */ + {0x369C, 0x4174}, + /* P_BL_P3Q0 */ + {0x36D4, 0x01EF}, + /* P_BL_P3Q1 */ + {0x36D6, 0x06CF}, + /* P_BL_P3Q2 */ + {0x36D8, 0x8D91}, + /* P_BL_P3Q3 */ + {0x36DA, 0x91F0}, + /* P_BL_P3Q4 */ + {0x36DC, 0x52EF}, + /* P_BL_P4Q0 */ + {0x3714, 0xA6D2}, + /* P_BL_P4Q1 */ + {0x3716, 0xA312}, + /* P_BL_P4Q2 */ + {0x3718, 0x2695}, + /* P_BL_P4Q3 */ + {0x371A, 0x3953}, + /* P_BL_P4Q4 */ + {0x371C, 0x9356}, + /* P_GB_P0Q0 */ + {0x361E, 0x7EAF}, + /* P_GB_P0Q1 */ + {0x3620, 0x2A4C}, + /* P_GB_P0Q2 */ + {0x3622, 0x49F0}, + {0x3624, 0xF1EC}, + /* P_GB_P0Q4 */ + {0x3626, 0xC670}, + /* P_GB_P1Q0 */ + {0x365E, 0x8E0C}, + /* P_GB_P1Q1 */ + {0x3660, 0xC2A9}, + /* P_GB_P1Q2 */ + {0x3662, 0x274F}, + /* P_GB_P1Q3 */ + {0x3664, 0xADAB}, + /* P_GB_P1Q4 */ + {0x3666, 0x8EF0}, + /* P_GB_P2Q0 */ + {0x369E, 0x09B1}, + /* P_GB_P2Q1 */ + {0x36A0, 0xAA2E}, + /* P_GB_P2Q2 */ + {0x36A2, 0xC3D3}, + /* P_GB_P2Q3 */ + {0x36A4, 0x7FAF}, + /* P_GB_P2Q4 */ + {0x36A6, 0x3F34}, + /* P_GB_P3Q0 */ + {0x36DE, 0x4C8F}, + /* P_GB_P3Q1 */ + {0x36E0, 0x886E}, + /* P_GB_P3Q2 */ + {0x36E2, 0xE831}, + /* P_GB_P3Q3 */ + {0x36E4, 0x1FD0}, + /* P_GB_P3Q4 */ + {0x36E6, 0x1192}, + /* P_GB_P4Q0 */ + {0x371E, 0xB952}, + /* P_GB_P4Q1 */ + {0x3720, 0x6DCF}, + /* P_GB_P4Q2 */ + {0x3722, 0x1B55}, + /* P_GB_P4Q3 */ + {0x3724, 0xA112}, + /* P_GB_P4Q4 */ + {0x3726, 0x82F6}, + /* POLY_ORIGIN_C */ + {0x3782, 0x0510}, + /* POLY_ORIGIN_R */ + {0x3784, 0x0390}, + /* POLY_SC_ENABLE */ + {0x3780, 0x8000}, +}; + +/* rolloff table for illuminant A */ +struct mt9p012_i2c_reg_conf mt9p012_rolloff_tbl[] = { + /* P_RD_P0Q0 */ + {0x360A, 0x7FEF}, + /* P_RD_P0Q1 */ + {0x360C, 0x232C}, + /* P_RD_P0Q2 */ + {0x360E, 0x7050}, + /* P_RD_P0Q3 */ + {0x3610, 0xF3CC}, + /* P_RD_P0Q4 */ + {0x3612, 0x89D1}, + /* P_RD_P1Q0 */ + {0x364A, 0xBE0D}, + /* P_RD_P1Q1 */ + {0x364C, 0x9ACB}, + /* P_RD_P1Q2 */ + {0x364E, 0x2150}, + /* P_RD_P1Q3 */ + {0x3650, 0xB26B}, + /* P_RD_P1Q4 */ + {0x3652, 0x9511}, + /* P_RD_P2Q0 */ + {0x368A, 0x2151}, + /* P_RD_P2Q1 */ + {0x368C, 0x00AD}, + /* P_RD_P2Q2 */ + {0x368E, 0x8334}, + /* P_RD_P2Q3 */ + {0x3690, 0x478E}, + /* P_RD_P2Q4 */ + {0x3692, 0x0515}, + /* P_RD_P3Q0 */ + {0x36CA, 0x0710}, + /* P_RD_P3Q1 */ + {0x36CC, 0x452D}, + /* P_RD_P3Q2 */ + {0x36CE, 0xF352}, + /* P_RD_P3Q3 */ + {0x36D0, 0x190F}, + /* P_RD_P3Q4 */ + {0x36D2, 0x4413}, + /* P_RD_P4Q0 */ + {0x370A, 0xD112}, + /* P_RD_P4Q1 */ + {0x370C, 0xF50F}, + /* P_RD_P4Q2 */ + {0x370E, 0x6375}, + /* P_RD_P4Q3 */ + {0x3710, 0xDC11}, + /* P_RD_P4Q4 */ + {0x3712, 0xD776}, + /* P_GR_P0Q0 */ + {0x3600, 0x1750}, + /* P_GR_P0Q1 */ + {0x3602, 0xF0AC}, + /* P_GR_P0Q2 */ + {0x3604, 0x4711}, + /* P_GR_P0Q3 */ + {0x3606, 0x07CE}, + /* P_GR_P0Q4 */ + {0x3608, 0x96B2}, + /* P_GR_P1Q0 */ + {0x3640, 0xA9AE}, + /* P_GR_P1Q1 */ + {0x3642, 0xF9AC}, + /* P_GR_P1Q2 */ + {0x3644, 0x39F1}, + /* P_GR_P1Q3 */ + {0x3646, 0x016F}, + /* P_GR_P1Q4 */ + {0x3648, 0x8AB2}, + /* P_GR_P2Q0 */ + {0x3680, 0x1752}, + /* P_GR_P2Q1 */ + {0x3682, 0x70F0}, + /* P_GR_P2Q2 */ + {0x3684, 0x83F5}, + /* P_GR_P2Q3 */ + {0x3686, 0x8392}, + /* P_GR_P2Q4 */ + {0x3688, 0x1FD6}, + /* P_GR_P3Q0 */ + {0x36C0, 0x1131}, + /* P_GR_P3Q1 */ + {0x36C2, 0x3DAF}, + /* P_GR_P3Q2 */ + {0x36C4, 0x89B4}, + /* P_GR_P3Q3 */ + {0x36C6, 0xA391}, + /* P_GR_P3Q4 */ + {0x36C8, 0x1334}, + /* P_GR_P4Q0 */ + {0x3700, 0xDC13}, + /* P_GR_P4Q1 */ + {0x3702, 0xD052}, + /* P_GR_P4Q2 */ + {0x3704, 0x5156}, + /* P_GR_P4Q3 */ + {0x3706, 0x1F13}, + /* P_GR_P4Q4 */ + {0x3708, 0x8C38}, + /* P_BL_P0Q0 */ + {0x3614, 0x0050}, + /* P_BL_P0Q1 */ + {0x3616, 0xBD4C}, + /* P_BL_P0Q2 */ + {0x3618, 0x41B0}, + /* P_BL_P0Q3 */ + {0x361A, 0x660D}, + /* P_BL_P0Q4 */ + {0x361C, 0xC590}, + /* P_BL_P1Q0 */ + {0x3654, 0x87EC}, + /* P_BL_P1Q1 */ + {0x3656, 0xE44C}, + /* P_BL_P1Q2 */ + {0x3658, 0x302E}, + /* P_BL_P1Q3 */ + {0x365A, 0x106E}, + /* P_BL_P1Q4 */ + {0x365C, 0xB58E}, + /* P_BL_P2Q0 */ + {0x3694, 0x0DD1}, + /* P_BL_P2Q1 */ + {0x3696, 0x2A50}, + /* P_BL_P2Q2 */ + {0x3698, 0xC793}, + /* P_BL_P2Q3 */ + {0x369A, 0xE8F1}, + /* P_BL_P2Q4 */ + {0x369C, 0x4174}, + /* P_BL_P3Q0 */ + {0x36D4, 0x01EF}, + /* P_BL_P3Q1 */ + {0x36D6, 0x06CF}, + /* P_BL_P3Q2 */ + {0x36D8, 0x8D91}, + /* P_BL_P3Q3 */ + {0x36DA, 0x91F0}, + /* P_BL_P3Q4 */ + {0x36DC, 0x52EF}, + /* P_BL_P4Q0 */ + {0x3714, 0xA6D2}, + /* P_BL_P4Q1 */ + {0x3716, 0xA312}, + /* P_BL_P4Q2 */ + {0x3718, 0x2695}, + /* P_BL_P4Q3 */ + {0x371A, 0x3953}, + /* P_BL_P4Q4 */ + {0x371C, 0x9356}, + /* P_GB_P0Q0 */ + {0x361E, 0x7EAF}, + /* P_GB_P0Q1 */ + {0x3620, 0x2A4C}, + /* P_GB_P0Q2 */ + {0x3622, 0x49F0}, + {0x3624, 0xF1EC}, + /* P_GB_P0Q4 */ + {0x3626, 0xC670}, + /* P_GB_P1Q0 */ + {0x365E, 0x8E0C}, + /* P_GB_P1Q1 */ + {0x3660, 0xC2A9}, + /* P_GB_P1Q2 */ + {0x3662, 0x274F}, + /* P_GB_P1Q3 */ + {0x3664, 0xADAB}, + /* P_GB_P1Q4 */ + {0x3666, 0x8EF0}, + /* P_GB_P2Q0 */ + {0x369E, 0x09B1}, + /* P_GB_P2Q1 */ + {0x36A0, 0xAA2E}, + /* P_GB_P2Q2 */ + {0x36A2, 0xC3D3}, + /* P_GB_P2Q3 */ + {0x36A4, 0x7FAF}, + /* P_GB_P2Q4 */ + {0x36A6, 0x3F34}, + /* P_GB_P3Q0 */ + {0x36DE, 0x4C8F}, + /* P_GB_P3Q1 */ + {0x36E0, 0x886E}, + /* P_GB_P3Q2 */ + {0x36E2, 0xE831}, + /* P_GB_P3Q3 */ + {0x36E4, 0x1FD0}, + /* P_GB_P3Q4 */ + {0x36E6, 0x1192}, + /* P_GB_P4Q0 */ + {0x371E, 0xB952}, + /* P_GB_P4Q1 */ + {0x3720, 0x6DCF}, + /* P_GB_P4Q2 */ + {0x3722, 0x1B55}, + /* P_GB_P4Q3 */ + {0x3724, 0xA112}, + /* P_GB_P4Q4 */ + {0x3726, 0x82F6}, + /* POLY_ORIGIN_C */ + {0x3782, 0x0510}, + /* POLY_ORIGIN_R */ + {0x3784, 0x0390}, + /* POLY_SC_ENABLE */ + {0x3780, 0x8000}, +}; + + +struct mt9p012_reg mt9p012_regs = { + .reg_pat = &mt9p012_reg_pat[0], + .reg_pat_size = ARRAY_SIZE(mt9p012_reg_pat), + .ttbl = &mt9p012_test_tbl[0], + .ttbl_size = ARRAY_SIZE(mt9p012_test_tbl), + .lctbl = &mt9p012_lc_tbl[0], + .lctbl_size = ARRAY_SIZE(mt9p012_lc_tbl), + .rftbl = &mt9p012_rolloff_tbl[0], + .rftbl_size = ARRAY_SIZE(mt9p012_rolloff_tbl) +}; + + diff --git a/trunk/drivers/staging/dream/camera/mt9t013.c b/trunk/drivers/staging/dream/camera/mt9t013.c new file mode 100644 index 000000000000..8fd7727ba234 --- /dev/null +++ b/trunk/drivers/staging/dream/camera/mt9t013.c @@ -0,0 +1,1497 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mt9t013.h" + +/*============================================================= + SENSOR REGISTER DEFINES +==============================================================*/ +#define MT9T013_REG_MODEL_ID 0x0000 +#define MT9T013_MODEL_ID 0x2600 +#define REG_GROUPED_PARAMETER_HOLD 0x0104 +#define GROUPED_PARAMETER_HOLD 0x0100 +#define GROUPED_PARAMETER_UPDATE 0x0000 +#define REG_COARSE_INT_TIME 0x3012 +#define REG_VT_PIX_CLK_DIV 0x0300 +#define REG_VT_SYS_CLK_DIV 0x0302 +#define REG_PRE_PLL_CLK_DIV 0x0304 +#define REG_PLL_MULTIPLIER 0x0306 +#define REG_OP_PIX_CLK_DIV 0x0308 +#define REG_OP_SYS_CLK_DIV 0x030A +#define REG_SCALE_M 0x0404 +#define REG_FRAME_LENGTH_LINES 0x300A +#define REG_LINE_LENGTH_PCK 0x300C +#define REG_X_ADDR_START 0x3004 +#define REG_Y_ADDR_START 0x3002 +#define REG_X_ADDR_END 0x3008 +#define REG_Y_ADDR_END 0x3006 +#define REG_X_OUTPUT_SIZE 0x034C +#define REG_Y_OUTPUT_SIZE 0x034E +#define REG_FINE_INT_TIME 0x3014 +#define REG_ROW_SPEED 0x3016 +#define MT9T013_REG_RESET_REGISTER 0x301A +#define MT9T013_RESET_REGISTER_PWON 0x10CC +#define MT9T013_RESET_REGISTER_PWOFF 0x1008 /* 0x10C8 stop streaming*/ +#define REG_READ_MODE 0x3040 +#define REG_GLOBAL_GAIN 0x305E +#define REG_TEST_PATTERN_MODE 0x3070 + + +enum mt9t013_test_mode { + TEST_OFF, + TEST_1, + TEST_2, + TEST_3 +}; + +enum mt9t013_resolution { + QTR_SIZE, + FULL_SIZE, + INVALID_SIZE +}; + +enum mt9t013_reg_update { + REG_INIT, /* registers that need to be updated during initialization */ + UPDATE_PERIODIC, /* registers that needs periodic I2C writes */ + UPDATE_ALL, /* all registers will be updated */ + UPDATE_INVALID +}; + +enum mt9t013_setting { + RES_PREVIEW, + RES_CAPTURE +}; + +/* actuator's Slave Address */ +#define MT9T013_AF_I2C_ADDR 0x18 + +/* +* AF Total steps parameters +*/ +#define MT9T013_TOTAL_STEPS_NEAR_TO_FAR 30 + +/* + * Time in milisecs for waiting for the sensor to reset. + */ +#define MT9T013_RESET_DELAY_MSECS 66 + +/* for 30 fps preview */ +#define MT9T013_DEFAULT_CLOCK_RATE 24000000 +#define MT9T013_DEFAULT_MAX_FPS 26 + + +/* FIXME: Changes from here */ +struct mt9t013_work { + struct work_struct work; +}; + +static struct mt9t013_work *mt9t013_sensorw; +static struct i2c_client *mt9t013_client; + +struct mt9t013_ctrl { + const struct msm_camera_sensor_info *sensordata; + + int sensormode; + uint32_t fps_divider; /* init to 1 * 0x00000400 */ + uint32_t pict_fps_divider; /* init to 1 * 0x00000400 */ + + uint16_t curr_lens_pos; + uint16_t init_curr_lens_pos; + uint16_t my_reg_gain; + uint32_t my_reg_line_count; + + enum mt9t013_resolution prev_res; + enum mt9t013_resolution pict_res; + enum mt9t013_resolution curr_res; + enum mt9t013_test_mode set_test; + + unsigned short imgaddr; +}; + + +static struct mt9t013_ctrl *mt9t013_ctrl; +static DECLARE_WAIT_QUEUE_HEAD(mt9t013_wait_queue); +DECLARE_MUTEX(mt9t013_sem); + +extern struct mt9t013_reg mt9t013_regs; /* from mt9t013_reg.c */ + +static int mt9t013_i2c_rxdata(unsigned short saddr, + unsigned char *rxdata, int length) +{ + struct i2c_msg msgs[] = { + { + .addr = saddr, + .flags = 0, + .len = 2, + .buf = rxdata, + }, + { + .addr = saddr, + .flags = I2C_M_RD, + .len = length, + .buf = rxdata, + }, + }; + + if (i2c_transfer(mt9t013_client->adapter, msgs, 2) < 0) { + pr_err("mt9t013_i2c_rxdata failed!\n"); + return -EIO; + } + + return 0; +} + +static int32_t mt9t013_i2c_read_w(unsigned short saddr, + unsigned short raddr, unsigned short *rdata) +{ + int32_t rc = 0; + unsigned char buf[4]; + + if (!rdata) + return -EIO; + + memset(buf, 0, sizeof(buf)); + + buf[0] = (raddr & 0xFF00)>>8; + buf[1] = (raddr & 0x00FF); + + rc = mt9t013_i2c_rxdata(saddr, buf, 2); + if (rc < 0) + return rc; + + *rdata = buf[0] << 8 | buf[1]; + + if (rc < 0) + pr_err("mt9t013_i2c_read failed!\n"); + + return rc; +} + +static int32_t mt9t013_i2c_txdata(unsigned short saddr, + unsigned char *txdata, int length) +{ + struct i2c_msg msg[] = { + { + .addr = saddr, + .flags = 0, + .len = length, + .buf = txdata, + }, + }; + + if (i2c_transfer(mt9t013_client->adapter, msg, 1) < 0) { + pr_err("mt9t013_i2c_txdata failed\n"); + return -EIO; + } + + return 0; +} + +static int32_t mt9t013_i2c_write_b(unsigned short saddr, + unsigned short waddr, unsigned short wdata) +{ + int32_t rc = -EIO; + unsigned char buf[2]; + + memset(buf, 0, sizeof(buf)); + buf[0] = waddr; + buf[1] = wdata; + rc = mt9t013_i2c_txdata(saddr, buf, 2); + + if (rc < 0) + pr_err("i2c_write failed, addr = 0x%x, val = 0x%x!\n", + waddr, wdata); + + return rc; +} + +static int32_t mt9t013_i2c_write_w(unsigned short saddr, + unsigned short waddr, unsigned short wdata) +{ + int32_t rc = -EIO; + unsigned char buf[4]; + + memset(buf, 0, sizeof(buf)); + buf[0] = (waddr & 0xFF00)>>8; + buf[1] = (waddr & 0x00FF); + buf[2] = (wdata & 0xFF00)>>8; + buf[3] = (wdata & 0x00FF); + + rc = mt9t013_i2c_txdata(saddr, buf, 4); + + if (rc < 0) + pr_err("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n", + waddr, wdata); + + return rc; +} + +static int32_t mt9t013_i2c_write_w_table( + struct mt9t013_i2c_reg_conf *reg_conf_tbl, int num_of_items_in_table) +{ + int i; + int32_t rc = -EIO; + + for (i = 0; i < num_of_items_in_table; i++) { + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + reg_conf_tbl->waddr, reg_conf_tbl->wdata); + if (rc < 0) + break; + reg_conf_tbl++; + } + + return rc; +} + +static int32_t mt9t013_test(enum mt9t013_test_mode mo) +{ + int32_t rc = 0; + + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_HOLD); + if (rc < 0) + return rc; + + if (mo == TEST_OFF) + return 0; + else { + rc = mt9t013_i2c_write_w_table(mt9t013_regs.ttbl, + mt9t013_regs.ttbl_size); + if (rc < 0) + return rc; + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + REG_TEST_PATTERN_MODE, (uint16_t)mo); + if (rc < 0) + return rc; + } + + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_UPDATE); + if (rc < 0) + return rc; + + return rc; +} + +static int32_t mt9t013_set_lc(void) +{ + int32_t rc; + + rc = mt9t013_i2c_write_w_table(mt9t013_regs.lctbl, mt9t013_regs.lctbl_size); + if (rc < 0) + return rc; + + return rc; +} + +static int32_t mt9t013_set_default_focus(uint8_t af_step) +{ + int32_t rc = 0; + uint8_t code_val_msb, code_val_lsb; + code_val_msb = 0x01; + code_val_lsb = af_step; + + /* Write the digital code for current to the actuator */ + rc = mt9t013_i2c_write_b(MT9T013_AF_I2C_ADDR>>1, + code_val_msb, code_val_lsb); + + mt9t013_ctrl->curr_lens_pos = 0; + mt9t013_ctrl->init_curr_lens_pos = 0; + return rc; +} + +static void mt9t013_get_pict_fps(uint16_t fps, uint16_t *pfps) +{ + /* input fps is preview fps in Q8 format */ + uint32_t divider; /*Q10 */ + uint32_t pclk_mult; /*Q10 */ + + if (mt9t013_ctrl->prev_res == QTR_SIZE) { + divider = + (uint32_t)( + ((mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines * + mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck) * + 0x00000400) / + (mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines * + mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck)); + + pclk_mult = + (uint32_t) ((mt9t013_regs.reg_pat[RES_CAPTURE].pll_multiplier * + 0x00000400) / + (mt9t013_regs.reg_pat[RES_PREVIEW].pll_multiplier)); + + } else { + /* full size resolution used for preview. */ + divider = 0x00000400; /*1.0 */ + pclk_mult = 0x00000400; /*1.0 */ + } + + /* Verify PCLK settings and frame sizes. */ + *pfps = + (uint16_t) (fps * divider * pclk_mult / + 0x00000400 / 0x00000400); +} + +static uint16_t mt9t013_get_prev_lines_pf(void) +{ + if (mt9t013_ctrl->prev_res == QTR_SIZE) + return mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines; + else + return mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines; +} + +static uint16_t mt9t013_get_prev_pixels_pl(void) +{ + if (mt9t013_ctrl->prev_res == QTR_SIZE) + return mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck; + else + return mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck; +} + +static uint16_t mt9t013_get_pict_lines_pf(void) +{ + return mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines; +} + +static uint16_t mt9t013_get_pict_pixels_pl(void) +{ + return mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck; +} + +static uint32_t mt9t013_get_pict_max_exp_lc(void) +{ + uint16_t snapshot_lines_per_frame; + + if (mt9t013_ctrl->pict_res == QTR_SIZE) { + snapshot_lines_per_frame = + mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines - 1; + } else { + snapshot_lines_per_frame = + mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines - 1; + } + + return snapshot_lines_per_frame * 24; +} + +static int32_t mt9t013_set_fps(struct fps_cfg *fps) +{ + /* input is new fps in Q8 format */ + int32_t rc = 0; + + mt9t013_ctrl->fps_divider = fps->fps_div; + mt9t013_ctrl->pict_fps_divider = fps->pict_fps_div; + + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_HOLD); + if (rc < 0) + return -EBUSY; + + CDBG("mt9t013_set_fps: fps_div is %d, frame_rate is %d\n", + fps->fps_div, + (uint16_t) (mt9t013_regs.reg_pat[RES_PREVIEW]. + frame_length_lines * + fps->fps_div/0x00000400)); + + CDBG("mt9t013_set_fps: fps_mult is %d, frame_rate is %d\n", + fps->f_mult, + (uint16_t)(mt9t013_regs.reg_pat[RES_PREVIEW]. + line_length_pck * + fps->f_mult / 0x00000400)); + + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + REG_LINE_LENGTH_PCK, + (uint16_t) ( + mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck * + fps->f_mult / 0x00000400)); + if (rc < 0) + return rc; + + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_UPDATE); + if (rc < 0) + return rc; + + return rc; +} + +static int32_t mt9t013_write_exp_gain(uint16_t gain, uint32_t line) +{ + const uint16_t max_legal_gain = 0x01FF; + uint32_t line_length_ratio = 0x00000400; + enum mt9t013_setting setting; + int32_t rc = 0; + + if (mt9t013_ctrl->sensormode == SENSOR_PREVIEW_MODE) { + mt9t013_ctrl->my_reg_gain = gain; + mt9t013_ctrl->my_reg_line_count = (uint16_t) line; + } + + if (gain > max_legal_gain) + gain = max_legal_gain; + + /* Verify no overflow */ + if (mt9t013_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) { + line = (uint32_t) (line * mt9t013_ctrl->fps_divider / + 0x00000400); + + setting = RES_PREVIEW; + + } else { + line = (uint32_t) (line * mt9t013_ctrl->pict_fps_divider / + 0x00000400); + + setting = RES_CAPTURE; + } + + /*Set digital gain to 1 */ + gain |= 0x0200; + + if ((mt9t013_regs.reg_pat[setting].frame_length_lines - 1) < line) { + + line_length_ratio = + (uint32_t) (line * 0x00000400) / + (mt9t013_regs.reg_pat[setting].frame_length_lines - 1); + } else + line_length_ratio = 0x00000400; + + /* There used to be PARAMETER_HOLD register write before and + * after REG_GLOBAL_GAIN & REG_COARSE_INIT_TIME. This causes + * aec oscillation. Hence removed. */ + + rc = mt9t013_i2c_write_w(mt9t013_client->addr, REG_GLOBAL_GAIN, gain); + if (rc < 0) + return rc; + + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + REG_COARSE_INT_TIME, + (uint16_t)((uint32_t) line * 0x00000400 / + line_length_ratio)); + if (rc < 0) + return rc; + + return rc; +} + +static int32_t mt9t013_set_pict_exp_gain(uint16_t gain, uint32_t line) +{ + int32_t rc = 0; + + rc = mt9t013_write_exp_gain(gain, line); + if (rc < 0) + return rc; + + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + MT9T013_REG_RESET_REGISTER, + 0x10CC | 0x0002); + + mdelay(5); + + /* camera_timed_wait(snapshot_wait*exposure_ratio); */ + return rc; +} + +static int32_t mt9t013_setting(enum mt9t013_reg_update rupdate, + enum mt9t013_setting rt) +{ + int32_t rc = 0; + + switch (rupdate) { + case UPDATE_PERIODIC: { + + if (rt == RES_PREVIEW || rt == RES_CAPTURE) { +#if 0 + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + MT9T013_REG_RESET_REGISTER, + MT9T013_RESET_REGISTER_PWOFF); + if (rc < 0) + return rc; +#endif + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_VT_PIX_CLK_DIV, + mt9t013_regs.reg_pat[rt].vt_pix_clk_div); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_VT_SYS_CLK_DIV, + mt9t013_regs.reg_pat[rt].vt_sys_clk_div); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_PRE_PLL_CLK_DIV, + mt9t013_regs.reg_pat[rt].pre_pll_clk_div); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_PLL_MULTIPLIER, + mt9t013_regs.reg_pat[rt].pll_multiplier); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_OP_PIX_CLK_DIV, + mt9t013_regs.reg_pat[rt].op_pix_clk_div); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_OP_SYS_CLK_DIV, + mt9t013_regs.reg_pat[rt].op_sys_clk_div); + if (rc < 0) + return rc; + + mdelay(5); + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_HOLD); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_ROW_SPEED, + mt9t013_regs.reg_pat[rt].row_speed); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_X_ADDR_START, + mt9t013_regs.reg_pat[rt].x_addr_start); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_X_ADDR_END, + mt9t013_regs.reg_pat[rt].x_addr_end); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_Y_ADDR_START, + mt9t013_regs.reg_pat[rt].y_addr_start); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_Y_ADDR_END, + mt9t013_regs.reg_pat[rt].y_addr_end); + if (rc < 0) + return rc; + + if (machine_is_sapphire()) { + if (rt == 0) + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + REG_READ_MODE, + 0x046F); + else + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + REG_READ_MODE, + 0x0027); + } else + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + REG_READ_MODE, + mt9t013_regs.reg_pat[rt].read_mode); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_SCALE_M, + mt9t013_regs.reg_pat[rt].scale_m); + if (rc < 0) + return rc; + + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_X_OUTPUT_SIZE, + mt9t013_regs.reg_pat[rt].x_output_size); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_Y_OUTPUT_SIZE, + mt9t013_regs.reg_pat[rt].y_output_size); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_LINE_LENGTH_PCK, + mt9t013_regs.reg_pat[rt].line_length_pck); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_FRAME_LENGTH_LINES, + (mt9t013_regs.reg_pat[rt].frame_length_lines * + mt9t013_ctrl->fps_divider / 0x00000400)); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_COARSE_INT_TIME, + mt9t013_regs.reg_pat[rt].coarse_int_time); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_FINE_INT_TIME, + mt9t013_regs.reg_pat[rt].fine_int_time); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_UPDATE); + if (rc < 0) + return rc; + + rc = mt9t013_test(mt9t013_ctrl->set_test); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + MT9T013_REG_RESET_REGISTER, + MT9T013_RESET_REGISTER_PWON); + if (rc < 0) + return rc; + + mdelay(5); + + return rc; + } + } + break; + + /*CAMSENSOR_REG_UPDATE_PERIODIC */ + case REG_INIT: { + if (rt == RES_PREVIEW || rt == RES_CAPTURE) { + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + MT9T013_REG_RESET_REGISTER, + MT9T013_RESET_REGISTER_PWOFF); + if (rc < 0) + /* MODE_SELECT, stop streaming */ + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_VT_PIX_CLK_DIV, + mt9t013_regs.reg_pat[rt].vt_pix_clk_div); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_VT_SYS_CLK_DIV, + mt9t013_regs.reg_pat[rt].vt_sys_clk_div); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_PRE_PLL_CLK_DIV, + mt9t013_regs.reg_pat[rt].pre_pll_clk_div); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_PLL_MULTIPLIER, + mt9t013_regs.reg_pat[rt].pll_multiplier); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_OP_PIX_CLK_DIV, + mt9t013_regs.reg_pat[rt].op_pix_clk_div); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_OP_SYS_CLK_DIV, + mt9t013_regs.reg_pat[rt].op_sys_clk_div); + if (rc < 0) + return rc; + + mdelay(5); + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_HOLD); + if (rc < 0) + return rc; + + /* additional power saving mode ok around 38.2MHz */ + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + 0x3084, 0x2409); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + 0x3092, 0x0A49); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + 0x3094, 0x4949); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + 0x3096, 0x4949); + if (rc < 0) + return rc; + + /* Set preview or snapshot mode */ + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_ROW_SPEED, + mt9t013_regs.reg_pat[rt].row_speed); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_X_ADDR_START, + mt9t013_regs.reg_pat[rt].x_addr_start); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_X_ADDR_END, + mt9t013_regs.reg_pat[rt].x_addr_end); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_Y_ADDR_START, + mt9t013_regs.reg_pat[rt].y_addr_start); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_Y_ADDR_END, + mt9t013_regs.reg_pat[rt].y_addr_end); + if (rc < 0) + return rc; + + if (machine_is_sapphire()) { + if (rt == 0) + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + REG_READ_MODE, + 0x046F); + else + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + REG_READ_MODE, + 0x0027); + } else + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + REG_READ_MODE, + mt9t013_regs.reg_pat[rt].read_mode); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_SCALE_M, + mt9t013_regs.reg_pat[rt].scale_m); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_X_OUTPUT_SIZE, + mt9t013_regs.reg_pat[rt].x_output_size); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_Y_OUTPUT_SIZE, + mt9t013_regs.reg_pat[rt].y_output_size); + if (rc < 0) + return 0; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_LINE_LENGTH_PCK, + mt9t013_regs.reg_pat[rt].line_length_pck); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_FRAME_LENGTH_LINES, + mt9t013_regs.reg_pat[rt].frame_length_lines); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_COARSE_INT_TIME, + mt9t013_regs.reg_pat[rt].coarse_int_time); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_FINE_INT_TIME, + mt9t013_regs.reg_pat[rt].fine_int_time); + if (rc < 0) + return rc; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_UPDATE); + if (rc < 0) + return rc; + + /* load lens shading */ + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_HOLD); + if (rc < 0) + return rc; + + /* most likely needs to be written only once. */ + rc = mt9t013_set_lc(); + if (rc < 0) + return -EBUSY; + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_UPDATE); + if (rc < 0) + return rc; + + rc = mt9t013_test(mt9t013_ctrl->set_test); + if (rc < 0) + return rc; + + mdelay(5); + + rc = + mt9t013_i2c_write_w(mt9t013_client->addr, + MT9T013_REG_RESET_REGISTER, + MT9T013_RESET_REGISTER_PWON); + if (rc < 0) + /* MODE_SELECT, stop streaming */ + return rc; + + CDBG("!!! mt9t013 !!! PowerOn is done!\n"); + mdelay(5); + return rc; + } + } /* case CAMSENSOR_REG_INIT: */ + break; + + /*CAMSENSOR_REG_INIT */ + default: + rc = -EINVAL; + break; + } /* switch (rupdate) */ + + return rc; +} + +static int32_t mt9t013_video_config(int mode, int res) +{ + int32_t rc; + + switch (res) { + case QTR_SIZE: + rc = mt9t013_setting(UPDATE_PERIODIC, RES_PREVIEW); + if (rc < 0) + return rc; + CDBG("sensor configuration done!\n"); + break; + + case FULL_SIZE: + rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE); + if (rc < 0) + return rc; + break; + + default: + return -EINVAL; + } /* switch */ + + mt9t013_ctrl->prev_res = res; + mt9t013_ctrl->curr_res = res; + mt9t013_ctrl->sensormode = mode; + + return mt9t013_write_exp_gain(mt9t013_ctrl->my_reg_gain, + mt9t013_ctrl->my_reg_line_count); +} + +static int32_t mt9t013_snapshot_config(int mode) +{ + int32_t rc = 0; + + rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE); + if (rc < 0) + return rc; + + mt9t013_ctrl->curr_res = mt9t013_ctrl->pict_res; + mt9t013_ctrl->sensormode = mode; + return rc; +} + +static int32_t mt9t013_raw_snapshot_config(int mode) +{ + int32_t rc = 0; + + rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE); + if (rc < 0) + return rc; + + mt9t013_ctrl->curr_res = mt9t013_ctrl->pict_res; + mt9t013_ctrl->sensormode = mode; + return rc; +} + +static int32_t mt9t013_power_down(void) +{ + int32_t rc = 0; + + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + MT9T013_REG_RESET_REGISTER, + MT9T013_RESET_REGISTER_PWOFF); + if (rc >= 0) + mdelay(5); + return rc; +} + +static int32_t mt9t013_move_focus(int direction, int32_t num_steps) +{ + int16_t step_direction; + int16_t actual_step; + int16_t next_position; + int16_t break_steps[4]; + uint8_t code_val_msb, code_val_lsb; + int16_t i; + + if (num_steps > MT9T013_TOTAL_STEPS_NEAR_TO_FAR) + num_steps = MT9T013_TOTAL_STEPS_NEAR_TO_FAR; + else if (num_steps == 0) + return -EINVAL; + + if (direction == MOVE_NEAR) + step_direction = 4; + else if (direction == MOVE_FAR) + step_direction = -4; + else + return -EINVAL; + + if (mt9t013_ctrl->curr_lens_pos < mt9t013_ctrl->init_curr_lens_pos) + mt9t013_ctrl->curr_lens_pos = mt9t013_ctrl->init_curr_lens_pos; + + actual_step = + (int16_t) (step_direction * + (int16_t) num_steps); + + for (i = 0; i < 4; i++) + break_steps[i] = + actual_step / 4 * (i + 1) - actual_step / 4 * i; + + for (i = 0; i < 4; i++) { + next_position = + (int16_t) + (mt9t013_ctrl->curr_lens_pos + break_steps[i]); + + if (next_position > 255) + next_position = 255; + else if (next_position < 0) + next_position = 0; + + code_val_msb = + ((next_position >> 4) << 2) | + ((next_position << 4) >> 6); + + code_val_lsb = + ((next_position & 0x03) << 6); + + /* Writing the digital code for current to the actuator */ + if (mt9t013_i2c_write_b(MT9T013_AF_I2C_ADDR>>1, + code_val_msb, code_val_lsb) < 0) + return -EBUSY; + + /* Storing the current lens Position */ + mt9t013_ctrl->curr_lens_pos = next_position; + + if (i < 3) + mdelay(1); + } /* for */ + + return 0; +} + +static int mt9t013_sensor_init_done(const struct msm_camera_sensor_info *data) +{ + gpio_direction_output(data->sensor_reset, 0); + gpio_free(data->sensor_reset); + return 0; +} + +static int mt9t013_probe_init_sensor(const struct msm_camera_sensor_info *data) +{ + int rc; + uint16_t chipid; + + rc = gpio_request(data->sensor_reset, "mt9t013"); + if (!rc) + gpio_direction_output(data->sensor_reset, 1); + else + goto init_probe_done; + + mdelay(20); + + /* RESET the sensor image part via I2C command */ + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + MT9T013_REG_RESET_REGISTER, 0x1009); + if (rc < 0) + goto init_probe_fail; + + /* 3. Read sensor Model ID: */ + rc = mt9t013_i2c_read_w(mt9t013_client->addr, + MT9T013_REG_MODEL_ID, &chipid); + + if (rc < 0) + goto init_probe_fail; + + CDBG("mt9t013 model_id = 0x%x\n", chipid); + + /* 4. Compare sensor ID to MT9T012VC ID: */ + if (chipid != MT9T013_MODEL_ID) { + rc = -ENODEV; + goto init_probe_fail; + } + + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + 0x3064, 0x0805); + if (rc < 0) + goto init_probe_fail; + + mdelay(MT9T013_RESET_DELAY_MSECS); + + goto init_probe_done; + + /* sensor: output enable */ +#if 0 + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + MT9T013_REG_RESET_REGISTER, + MT9T013_RESET_REGISTER_PWON); + + /* if this fails, the sensor is not the MT9T013 */ + rc = mt9t013_set_default_focus(0); +#endif + +init_probe_fail: + gpio_direction_output(data->sensor_reset, 0); + gpio_free(data->sensor_reset); +init_probe_done: + return rc; +} + +static int32_t mt9t013_poweron_af(void) +{ + int32_t rc = 0; + + /* enable AF actuator */ + CDBG("enable AF actuator, gpio = %d\n", + mt9t013_ctrl->sensordata->vcm_pwd); + rc = gpio_request(mt9t013_ctrl->sensordata->vcm_pwd, "mt9t013"); + if (!rc) { + gpio_direction_output(mt9t013_ctrl->sensordata->vcm_pwd, 0); + mdelay(20); + rc = mt9t013_set_default_focus(0); + } else + pr_err("%s, gpio_request failed (%d)!\n", __func__, rc); + return rc; +} + +static void mt9t013_poweroff_af(void) +{ + gpio_direction_output(mt9t013_ctrl->sensordata->vcm_pwd, 1); + gpio_free(mt9t013_ctrl->sensordata->vcm_pwd); +} + +int mt9t013_sensor_open_init(const struct msm_camera_sensor_info *data) +{ + int32_t rc; + + mt9t013_ctrl = kzalloc(sizeof(struct mt9t013_ctrl), GFP_KERNEL); + if (!mt9t013_ctrl) { + pr_err("mt9t013_init failed!\n"); + rc = -ENOMEM; + goto init_done; + } + + mt9t013_ctrl->fps_divider = 1 * 0x00000400; + mt9t013_ctrl->pict_fps_divider = 1 * 0x00000400; + mt9t013_ctrl->set_test = TEST_OFF; + mt9t013_ctrl->prev_res = QTR_SIZE; + mt9t013_ctrl->pict_res = FULL_SIZE; + + if (data) + mt9t013_ctrl->sensordata = data; + + /* enable mclk first */ + msm_camio_clk_rate_set(MT9T013_DEFAULT_CLOCK_RATE); + mdelay(20); + + msm_camio_camif_pad_reg_reset(); + mdelay(20); + + rc = mt9t013_probe_init_sensor(data); + if (rc < 0) + goto init_fail; + + if (mt9t013_ctrl->prev_res == QTR_SIZE) + rc = mt9t013_setting(REG_INIT, RES_PREVIEW); + else + rc = mt9t013_setting(REG_INIT, RES_CAPTURE); + + if (rc >= 0) + rc = mt9t013_poweron_af(); + + if (rc < 0) + goto init_fail; + else + goto init_done; + +init_fail: + kfree(mt9t013_ctrl); +init_done: + return rc; +} + +static int mt9t013_init_client(struct i2c_client *client) +{ + /* Initialize the MSM_CAMI2C Chip */ + init_waitqueue_head(&mt9t013_wait_queue); + return 0; +} + + +static int32_t mt9t013_set_sensor_mode(int mode, int res) +{ + int32_t rc = 0; + rc = mt9t013_i2c_write_w(mt9t013_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_HOLD); + if (rc < 0) + return rc; + + switch (mode) { + case SENSOR_PREVIEW_MODE: + rc = mt9t013_video_config(mode, res); + break; + + case SENSOR_SNAPSHOT_MODE: + rc = mt9t013_snapshot_config(mode); + break; + + case SENSOR_RAW_SNAPSHOT_MODE: + rc = mt9t013_raw_snapshot_config(mode); + break; + + default: + return -EINVAL; + } + + /* FIXME: what should we do if rc < 0? */ + if (rc >= 0) + return mt9t013_i2c_write_w(mt9t013_client->addr, + REG_GROUPED_PARAMETER_HOLD, + GROUPED_PARAMETER_UPDATE); + return rc; +} + +int mt9t013_sensor_config(void __user *argp) +{ + struct sensor_cfg_data cdata; + long rc = 0; + + if (copy_from_user(&cdata, (void *)argp, + sizeof(struct sensor_cfg_data))) + return -EFAULT; + + down(&mt9t013_sem); + + CDBG("mt9t013_sensor_config: cfgtype = %d\n", cdata.cfgtype); + switch (cdata.cfgtype) { + case CFG_GET_PICT_FPS: + mt9t013_get_pict_fps(cdata.cfg.gfps.prevfps, + &(cdata.cfg.gfps.pictfps)); + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_GET_PREV_L_PF: + cdata.cfg.prevl_pf = mt9t013_get_prev_lines_pf(); + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_GET_PREV_P_PL: + cdata.cfg.prevp_pl = mt9t013_get_prev_pixels_pl(); + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_GET_PICT_L_PF: + cdata.cfg.pictl_pf = mt9t013_get_pict_lines_pf(); + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_GET_PICT_P_PL: + cdata.cfg.pictp_pl = + mt9t013_get_pict_pixels_pl(); + + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_GET_PICT_MAX_EXP_LC: + cdata.cfg.pict_max_exp_lc = + mt9t013_get_pict_max_exp_lc(); + + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_SET_FPS: + case CFG_SET_PICT_FPS: + rc = mt9t013_set_fps(&(cdata.cfg.fps)); + break; + + case CFG_SET_EXP_GAIN: + rc = mt9t013_write_exp_gain(cdata.cfg.exp_gain.gain, + cdata.cfg.exp_gain.line); + break; + + case CFG_SET_PICT_EXP_GAIN: + rc = mt9t013_set_pict_exp_gain(cdata.cfg.exp_gain.gain, + cdata.cfg.exp_gain.line); + break; + + case CFG_SET_MODE: + rc = mt9t013_set_sensor_mode(cdata.mode, cdata.rs); + break; + + case CFG_PWR_DOWN: + rc = mt9t013_power_down(); + break; + + case CFG_MOVE_FOCUS: + rc = mt9t013_move_focus(cdata.cfg.focus.dir, + cdata.cfg.focus.steps); + break; + + case CFG_SET_DEFAULT_FOCUS: + rc = mt9t013_set_default_focus(cdata.cfg.focus.steps); + break; + + case CFG_GET_AF_MAX_STEPS: + cdata.max_steps = MT9T013_TOTAL_STEPS_NEAR_TO_FAR; + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_SET_EFFECT: + default: + rc = -EINVAL; + break; + } + + up(&mt9t013_sem); + return rc; +} + +int mt9t013_sensor_release(void) +{ + int rc = -EBADF; + + down(&mt9t013_sem); + + mt9t013_poweroff_af(); + mt9t013_power_down(); + + gpio_direction_output(mt9t013_ctrl->sensordata->sensor_reset, + 0); + gpio_free(mt9t013_ctrl->sensordata->sensor_reset); + + kfree(mt9t013_ctrl); + + up(&mt9t013_sem); + CDBG("mt9t013_release completed!\n"); + return rc; +} + +static int mt9t013_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int rc = 0; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + rc = -ENOTSUPP; + goto probe_failure; + } + + mt9t013_sensorw = + kzalloc(sizeof(struct mt9t013_work), GFP_KERNEL); + + if (!mt9t013_sensorw) { + rc = -ENOMEM; + goto probe_failure; + } + + i2c_set_clientdata(client, mt9t013_sensorw); + mt9t013_init_client(client); + mt9t013_client = client; + mt9t013_client->addr = mt9t013_client->addr >> 1; + mdelay(50); + + CDBG("i2c probe ok\n"); + return 0; + +probe_failure: + kfree(mt9t013_sensorw); + mt9t013_sensorw = NULL; + pr_err("i2c probe failure %d\n", rc); + return rc; +} + +static const struct i2c_device_id mt9t013_i2c_id[] = { + { "mt9t013", 0}, + { } +}; + +static struct i2c_driver mt9t013_i2c_driver = { + .id_table = mt9t013_i2c_id, + .probe = mt9t013_i2c_probe, + .remove = __exit_p(mt9t013_i2c_remove), + .driver = { + .name = "mt9t013", + }, +}; + +static int mt9t013_sensor_probe( + const struct msm_camera_sensor_info *info, + struct msm_sensor_ctrl *s) +{ + /* We expect this driver to match with the i2c device registered + * in the board file immediately. */ + int rc = i2c_add_driver(&mt9t013_i2c_driver); + if (rc < 0 || mt9t013_client == NULL) { + rc = -ENOTSUPP; + goto probe_done; + } + + /* enable mclk first */ + msm_camio_clk_rate_set(MT9T013_DEFAULT_CLOCK_RATE); + mdelay(20); + + rc = mt9t013_probe_init_sensor(info); + if (rc < 0) { + i2c_del_driver(&mt9t013_i2c_driver); + goto probe_done; + } + + s->s_init = mt9t013_sensor_open_init; + s->s_release = mt9t013_sensor_release; + s->s_config = mt9t013_sensor_config; + mt9t013_sensor_init_done(info); + +probe_done: + return rc; +} + +static int __mt9t013_probe(struct platform_device *pdev) +{ + return msm_camera_drv_start(pdev, mt9t013_sensor_probe); +} + +static struct platform_driver msm_camera_driver = { + .probe = __mt9t013_probe, + .driver = { + .name = "msm_camera_mt9t013", + .owner = THIS_MODULE, + }, +}; + +static int __init mt9t013_init(void) +{ + return platform_driver_register(&msm_camera_driver); +} + +module_init(mt9t013_init); diff --git a/trunk/drivers/staging/dream/camera/mt9t013.h b/trunk/drivers/staging/dream/camera/mt9t013.h new file mode 100644 index 000000000000..9bce2036e3b6 --- /dev/null +++ b/trunk/drivers/staging/dream/camera/mt9t013.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ + +#ifndef MT9T013_H +#define MT9T013_H + +#include + +struct reg_struct { + uint16_t vt_pix_clk_div; /* 0x0300 */ + uint16_t vt_sys_clk_div; /* 0x0302 */ + uint16_t pre_pll_clk_div; /* 0x0304 */ + uint16_t pll_multiplier; /* 0x0306 */ + uint16_t op_pix_clk_div; /* 0x0308 */ + uint16_t op_sys_clk_div; /* 0x030A */ + uint16_t scale_m; /* 0x0404 */ + uint16_t row_speed; /* 0x3016 */ + uint16_t x_addr_start; /* 0x3004 */ + uint16_t x_addr_end; /* 0x3008 */ + uint16_t y_addr_start; /* 0x3002 */ + uint16_t y_addr_end; /* 0x3006 */ + uint16_t read_mode; /* 0x3040 */ + uint16_t x_output_size; /* 0x034C */ + uint16_t y_output_size; /* 0x034E */ + uint16_t line_length_pck; /* 0x300C */ + uint16_t frame_length_lines; /* 0x300A */ + uint16_t coarse_int_time; /* 0x3012 */ + uint16_t fine_int_time; /* 0x3014 */ +}; + +struct mt9t013_i2c_reg_conf { + unsigned short waddr; + unsigned short wdata; +}; + +struct mt9t013_reg { + struct reg_struct *reg_pat; + uint16_t reg_pat_size; + struct mt9t013_i2c_reg_conf *ttbl; + uint16_t ttbl_size; + struct mt9t013_i2c_reg_conf *lctbl; + uint16_t lctbl_size; + struct mt9t013_i2c_reg_conf *rftbl; + uint16_t rftbl_size; +}; + +#endif /* #define MT9T013_H */ diff --git a/trunk/drivers/staging/dream/camera/mt9t013_reg.c b/trunk/drivers/staging/dream/camera/mt9t013_reg.c new file mode 100644 index 000000000000..ba0a1d4b4d5f --- /dev/null +++ b/trunk/drivers/staging/dream/camera/mt9t013_reg.c @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2009 QUALCOMM Incorporated. + */ + +#include "mt9t013.h" +#include + +struct reg_struct const mt9t013_reg_pat[2] = { + { /* Preview 2x2 binning 20fps, pclk MHz, MCLK 24MHz */ + /* vt_pix_clk_div:REG=0x0300 update get_snapshot_fps + * if this change */ + 8, + + /* vt_sys_clk_div: REG=0x0302 update get_snapshot_fps + * if this change */ + 1, + + /* pre_pll_clk_div REG=0x0304 update get_snapshot_fps + * if this change */ + 2, + + /* pll_multiplier REG=0x0306 60 for 30fps preview, 40 + * for 20fps preview + * 46 for 30fps preview, try 47/48 to increase further */ + 46, + + /* op_pix_clk_div REG=0x0308 */ + 8, + + /* op_sys_clk_div REG=0x030A */ + 1, + + /* scale_m REG=0x0404 */ + 16, + + /* row_speed REG=0x3016 */ + 0x0111, + + /* x_addr_start REG=0x3004 */ + 8, + + /* x_addr_end REG=0x3008 */ + 2053, + + /* y_addr_start REG=0x3002 */ + 8, + + /* y_addr_end REG=0x3006 */ + 1541, + + /* read_mode REG=0x3040 */ + 0x046C, + + /* x_output_size REG=0x034C */ + 1024, + + /* y_output_size REG=0x034E */ + 768, + + /* line_length_pck REG=0x300C */ + 2616, + + /* frame_length_lines REG=0x300A */ + 916, + + /* coarse_int_time REG=0x3012 */ + 16, + + /* fine_int_time REG=0x3014 */ + 1461 + }, + { /*Snapshot */ + /* vt_pix_clk_div REG=0x0300 update get_snapshot_fps + * if this change */ + 8, + + /* vt_sys_clk_div REG=0x0302 update get_snapshot_fps + * if this change */ + 1, + + /* pre_pll_clk_div REG=0x0304 update get_snapshot_fps + * if this change */ + 2, + + /* pll_multiplier REG=0x0306 50 for 15fps snapshot, + * 40 for 10fps snapshot + * 46 for 30fps snapshot, try 47/48 to increase further */ + 46, + + /* op_pix_clk_div REG=0x0308 */ + 8, + + /* op_sys_clk_div REG=0x030A */ + 1, + + /* scale_m REG=0x0404 */ + 16, + + /* row_speed REG=0x3016 */ + 0x0111, + + /* x_addr_start REG=0x3004 */ + 8, + + /* x_addr_end REG=0x3008 */ + 2071, + + /* y_addr_start REG=0x3002 */ + 8, + + /* y_addr_end REG=0x3006 */ + 1551, + + /* read_mode REG=0x3040 */ + 0x0024, + + /* x_output_size REG=0x034C */ + 2064, + + /* y_output_size REG=0x034E */ + 1544, + + /* line_length_pck REG=0x300C */ + 2952, + + /* frame_length_lines REG=0x300A */ + 1629, + + /* coarse_int_time REG=0x3012 */ + 16, + + /* fine_int_time REG=0x3014 */ + 733 + } +}; + +struct mt9t013_i2c_reg_conf mt9t013_test_tbl[] = { + { 0x3044, 0x0544 & 0xFBFF }, + { 0x30CA, 0x0004 | 0x0001 }, + { 0x30D4, 0x9020 & 0x7FFF }, + { 0x31E0, 0x0003 & 0xFFFE }, + { 0x3180, 0x91FF & 0x7FFF }, + { 0x301A, (0x10CC | 0x8000) & 0xFFF7 }, + { 0x301E, 0x0000 }, + { 0x3780, 0x0000 }, +}; + +/* [Lens shading 85 Percent TL84] */ +struct mt9t013_i2c_reg_conf mt9t013_lc_tbl[] = { + { 0x360A, 0x0290 }, /* P_RD_P0Q0 */ + { 0x360C, 0xC92D }, /* P_RD_P0Q1 */ + { 0x360E, 0x0771 }, /* P_RD_P0Q2 */ + { 0x3610, 0xE38C }, /* P_RD_P0Q3 */ + { 0x3612, 0xD74F }, /* P_RD_P0Q4 */ + { 0x364A, 0x168C }, /* P_RD_P1Q0 */ + { 0x364C, 0xCACB }, /* P_RD_P1Q1 */ + { 0x364E, 0x8C4C }, /* P_RD_P1Q2 */ + { 0x3650, 0x0BEA }, /* P_RD_P1Q3 */ + { 0x3652, 0xDC0F }, /* P_RD_P1Q4 */ + { 0x368A, 0x70B0 }, /* P_RD_P2Q0 */ + { 0x368C, 0x200B }, /* P_RD_P2Q1 */ + { 0x368E, 0x30B2 }, /* P_RD_P2Q2 */ + { 0x3690, 0xD04F }, /* P_RD_P2Q3 */ + { 0x3692, 0xACF5 }, /* P_RD_P2Q4 */ + { 0x36CA, 0xF7C9 }, /* P_RD_P3Q0 */ + { 0x36CC, 0x2AED }, /* P_RD_P3Q1 */ + { 0x36CE, 0xA652 }, /* P_RD_P3Q2 */ + { 0x36D0, 0x8192 }, /* P_RD_P3Q3 */ + { 0x36D2, 0x3A15 }, /* P_RD_P3Q4 */ + { 0x370A, 0xDA30 }, /* P_RD_P4Q0 */ + { 0x370C, 0x2E2F }, /* P_RD_P4Q1 */ + { 0x370E, 0xBB56 }, /* P_RD_P4Q2 */ + { 0x3710, 0x8195 }, /* P_RD_P4Q3 */ + { 0x3712, 0x02F9 }, /* P_RD_P4Q4 */ + { 0x3600, 0x0230 }, /* P_GR_P0Q0 */ + { 0x3602, 0x58AD }, /* P_GR_P0Q1 */ + { 0x3604, 0x18D1 }, /* P_GR_P0Q2 */ + { 0x3606, 0x260D }, /* P_GR_P0Q3 */ + { 0x3608, 0xF530 }, /* P_GR_P0Q4 */ + { 0x3640, 0x17EB }, /* P_GR_P1Q0 */ + { 0x3642, 0x3CAB }, /* P_GR_P1Q1 */ + { 0x3644, 0x87CE }, /* P_GR_P1Q2 */ + { 0x3646, 0xC02E }, /* P_GR_P1Q3 */ + { 0x3648, 0xF48F }, /* P_GR_P1Q4 */ + { 0x3680, 0x5350 }, /* P_GR_P2Q0 */ + { 0x3682, 0x7EAF }, /* P_GR_P2Q1 */ + { 0x3684, 0x4312 }, /* P_GR_P2Q2 */ + { 0x3686, 0xC652 }, /* P_GR_P2Q3 */ + { 0x3688, 0xBC15 }, /* P_GR_P2Q4 */ + { 0x36C0, 0xB8AD }, /* P_GR_P3Q0 */ + { 0x36C2, 0xBDCD }, /* P_GR_P3Q1 */ + { 0x36C4, 0xE4B2 }, /* P_GR_P3Q2 */ + { 0x36C6, 0xB50F }, /* P_GR_P3Q3 */ + { 0x36C8, 0x5B95 }, /* P_GR_P3Q4 */ + { 0x3700, 0xFC90 }, /* P_GR_P4Q0 */ + { 0x3702, 0x8C51 }, /* P_GR_P4Q1 */ + { 0x3704, 0xCED6 }, /* P_GR_P4Q2 */ + { 0x3706, 0xB594 }, /* P_GR_P4Q3 */ + { 0x3708, 0x0A39 }, /* P_GR_P4Q4 */ + { 0x3614, 0x0230 }, /* P_BL_P0Q0 */ + { 0x3616, 0x160D }, /* P_BL_P0Q1 */ + { 0x3618, 0x08D1 }, /* P_BL_P0Q2 */ + { 0x361A, 0x98AB }, /* P_BL_P0Q3 */ + { 0x361C, 0xEA50 }, /* P_BL_P0Q4 */ + { 0x3654, 0xB4EA }, /* P_BL_P1Q0 */ + { 0x3656, 0xEA6C }, /* P_BL_P1Q1 */ + { 0x3658, 0xFE08 }, /* P_BL_P1Q2 */ + { 0x365A, 0x2C6E }, /* P_BL_P1Q3 */ + { 0x365C, 0xEB0E }, /* P_BL_P1Q4 */ + { 0x3694, 0x6DF0 }, /* P_BL_P2Q0 */ + { 0x3696, 0x3ACF }, /* P_BL_P2Q1 */ + { 0x3698, 0x3E0F }, /* P_BL_P2Q2 */ + { 0x369A, 0xB2B1 }, /* P_BL_P2Q3 */ + { 0x369C, 0xC374 }, /* P_BL_P2Q4 */ + { 0x36D4, 0xF2AA }, /* P_BL_P3Q0 */ + { 0x36D6, 0x8CCC }, /* P_BL_P3Q1 */ + { 0x36D8, 0xDEF2 }, /* P_BL_P3Q2 */ + { 0x36DA, 0xFA11 }, /* P_BL_P3Q3 */ + { 0x36DC, 0x42F5 }, /* P_BL_P3Q4 */ + { 0x3714, 0xF4F1 }, /* P_BL_P4Q0 */ + { 0x3716, 0xF6F0 }, /* P_BL_P4Q1 */ + { 0x3718, 0x8FD6 }, /* P_BL_P4Q2 */ + { 0x371A, 0xEA14 }, /* P_BL_P4Q3 */ + { 0x371C, 0x6338 }, /* P_BL_P4Q4 */ + { 0x361E, 0x0350 }, /* P_GB_P0Q0 */ + { 0x3620, 0x91AE }, /* P_GB_P0Q1 */ + { 0x3622, 0x0571 }, /* P_GB_P0Q2 */ + { 0x3624, 0x100D }, /* P_GB_P0Q3 */ + { 0x3626, 0xCA70 }, /* P_GB_P0Q4 */ + { 0x365E, 0xE6CB }, /* P_GB_P1Q0 */ + { 0x3660, 0x50ED }, /* P_GB_P1Q1 */ + { 0x3662, 0x3DAE }, /* P_GB_P1Q2 */ + { 0x3664, 0xAA4F }, /* P_GB_P1Q3 */ + { 0x3666, 0xDC50 }, /* P_GB_P1Q4 */ + { 0x369E, 0x5470 }, /* P_GB_P2Q0 */ + { 0x36A0, 0x1F6E }, /* P_GB_P2Q1 */ + { 0x36A2, 0x6671 }, /* P_GB_P2Q2 */ + { 0x36A4, 0xC010 }, /* P_GB_P2Q3 */ + { 0x36A6, 0x8DF5 }, /* P_GB_P2Q4 */ + { 0x36DE, 0x0B0C }, /* P_GB_P3Q0 */ + { 0x36E0, 0x84CE }, /* P_GB_P3Q1 */ + { 0x36E2, 0x8493 }, /* P_GB_P3Q2 */ + { 0x36E4, 0xA610 }, /* P_GB_P3Q3 */ + { 0x36E6, 0x50B5 }, /* P_GB_P3Q4 */ + { 0x371E, 0x9651 }, /* P_GB_P4Q0 */ + { 0x3720, 0x1EAB }, /* P_GB_P4Q1 */ + { 0x3722, 0xAF76 }, /* P_GB_P4Q2 */ + { 0x3724, 0xE4F4 }, /* P_GB_P4Q3 */ + { 0x3726, 0x79F8 }, /* P_GB_P4Q4 */ + { 0x3782, 0x0410 }, /* POLY_ORIGIN_C */ + { 0x3784, 0x0320 }, /* POLY_ORIGIN_R */ + { 0x3780, 0x8000 } /* POLY_SC_ENABLE */ +}; + +struct mt9t013_reg mt9t013_regs = { + .reg_pat = &mt9t013_reg_pat[0], + .reg_pat_size = ARRAY_SIZE(mt9t013_reg_pat), + .ttbl = &mt9t013_test_tbl[0], + .ttbl_size = ARRAY_SIZE(mt9t013_test_tbl), + .lctbl = &mt9t013_lc_tbl[0], + .lctbl_size = ARRAY_SIZE(mt9t013_lc_tbl), + .rftbl = &mt9t013_lc_tbl[0], /* &mt9t013_rolloff_tbl[0], */ + .rftbl_size = ARRAY_SIZE(mt9t013_lc_tbl) +}; + + diff --git a/trunk/drivers/staging/dream/camera/s5k3e2fx.c b/trunk/drivers/staging/dream/camera/s5k3e2fx.c new file mode 100644 index 000000000000..1459903a339d --- /dev/null +++ b/trunk/drivers/staging/dream/camera/s5k3e2fx.c @@ -0,0 +1,1307 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "s5k3e2fx.h" + +#define S5K3E2FX_REG_MODEL_ID 0x0000 +#define S5K3E2FX_MODEL_ID 0x3E2F + +/* PLL Registers */ +#define REG_PRE_PLL_CLK_DIV 0x0305 +#define REG_PLL_MULTIPLIER_MSB 0x0306 +#define REG_PLL_MULTIPLIER_LSB 0x0307 +#define REG_VT_PIX_CLK_DIV 0x0301 +#define REG_VT_SYS_CLK_DIV 0x0303 +#define REG_OP_PIX_CLK_DIV 0x0309 +#define REG_OP_SYS_CLK_DIV 0x030B + +/* Data Format Registers */ +#define REG_CCP_DATA_FORMAT_MSB 0x0112 +#define REG_CCP_DATA_FORMAT_LSB 0x0113 + +/* Output Size */ +#define REG_X_OUTPUT_SIZE_MSB 0x034C +#define REG_X_OUTPUT_SIZE_LSB 0x034D +#define REG_Y_OUTPUT_SIZE_MSB 0x034E +#define REG_Y_OUTPUT_SIZE_LSB 0x034F + +/* Binning */ +#define REG_X_EVEN_INC 0x0381 +#define REG_X_ODD_INC 0x0383 +#define REG_Y_EVEN_INC 0x0385 +#define REG_Y_ODD_INC 0x0387 +/*Reserved register */ +#define REG_BINNING_ENABLE 0x3014 + +/* Frame Fotmat */ +#define REG_FRAME_LENGTH_LINES_MSB 0x0340 +#define REG_FRAME_LENGTH_LINES_LSB 0x0341 +#define REG_LINE_LENGTH_PCK_MSB 0x0342 +#define REG_LINE_LENGTH_PCK_LSB 0x0343 + +/* MSR setting */ +/* Reserved registers */ +#define REG_SHADE_CLK_ENABLE 0x30AC +#define REG_SEL_CCP 0x30C4 +#define REG_VPIX 0x3024 +#define REG_CLAMP_ON 0x3015 +#define REG_OFFSET 0x307E + +/* CDS timing settings */ +/* Reserved registers */ +#define REG_LD_START 0x3000 +#define REG_LD_END 0x3001 +#define REG_SL_START 0x3002 +#define REG_SL_END 0x3003 +#define REG_RX_START 0x3004 +#define REG_S1_START 0x3005 +#define REG_S1_END 0x3006 +#define REG_S1S_START 0x3007 +#define REG_S1S_END 0x3008 +#define REG_S3_START 0x3009 +#define REG_S3_END 0x300A +#define REG_CMP_EN_START 0x300B +#define REG_CLP_SL_START 0x300C +#define REG_CLP_SL_END 0x300D +#define REG_OFF_START 0x300E +#define REG_RMP_EN_START 0x300F +#define REG_TX_START 0x3010 +#define REG_TX_END 0x3011 +#define REG_STX_WIDTH 0x3012 +#define REG_TYPE1_AF_ENABLE 0x3130 +#define DRIVER_ENABLED 0x0001 +#define AUTO_START_ENABLED 0x0010 +#define REG_NEW_POSITION 0x3131 +#define REG_3152_RESERVED 0x3152 +#define REG_315A_RESERVED 0x315A +#define REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB 0x0204 +#define REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB 0x0205 +#define REG_FINE_INTEGRATION_TIME 0x0200 +#define REG_COARSE_INTEGRATION_TIME 0x0202 +#define REG_COARSE_INTEGRATION_TIME_LSB 0x0203 + +/* Mode select register */ +#define S5K3E2FX_REG_MODE_SELECT 0x0100 +#define S5K3E2FX_MODE_SELECT_STREAM 0x01 /* start streaming */ +#define S5K3E2FX_MODE_SELECT_SW_STANDBY 0x00 /* software standby */ +#define S5K3E2FX_REG_SOFTWARE_RESET 0x0103 +#define S5K3E2FX_SOFTWARE_RESET 0x01 +#define REG_TEST_PATTERN_MODE 0x0601 + +struct reg_struct { + uint8_t pre_pll_clk_div; /* 0x0305 */ + uint8_t pll_multiplier_msb; /* 0x0306 */ + uint8_t pll_multiplier_lsb; /* 0x0307 */ + uint8_t vt_pix_clk_div; /* 0x0301 */ + uint8_t vt_sys_clk_div; /* 0x0303 */ + uint8_t op_pix_clk_div; /* 0x0309 */ + uint8_t op_sys_clk_div; /* 0x030B */ + uint8_t ccp_data_format_msb; /* 0x0112 */ + uint8_t ccp_data_format_lsb; /* 0x0113 */ + uint8_t x_output_size_msb; /* 0x034C */ + uint8_t x_output_size_lsb; /* 0x034D */ + uint8_t y_output_size_msb; /* 0x034E */ + uint8_t y_output_size_lsb; /* 0x034F */ + uint8_t x_even_inc; /* 0x0381 */ + uint8_t x_odd_inc; /* 0x0383 */ + uint8_t y_even_inc; /* 0x0385 */ + uint8_t y_odd_inc; /* 0x0387 */ + uint8_t binning_enable; /* 0x3014 */ + uint8_t frame_length_lines_msb; /* 0x0340 */ + uint8_t frame_length_lines_lsb; /* 0x0341 */ + uint8_t line_length_pck_msb; /* 0x0342 */ + uint8_t line_length_pck_lsb; /* 0x0343 */ + uint8_t shade_clk_enable ; /* 0x30AC */ + uint8_t sel_ccp; /* 0x30C4 */ + uint8_t vpix; /* 0x3024 */ + uint8_t clamp_on; /* 0x3015 */ + uint8_t offset; /* 0x307E */ + uint8_t ld_start; /* 0x3000 */ + uint8_t ld_end; /* 0x3001 */ + uint8_t sl_start; /* 0x3002 */ + uint8_t sl_end; /* 0x3003 */ + uint8_t rx_start; /* 0x3004 */ + uint8_t s1_start; /* 0x3005 */ + uint8_t s1_end; /* 0x3006 */ + uint8_t s1s_start; /* 0x3007 */ + uint8_t s1s_end; /* 0x3008 */ + uint8_t s3_start; /* 0x3009 */ + uint8_t s3_end; /* 0x300A */ + uint8_t cmp_en_start; /* 0x300B */ + uint8_t clp_sl_start; /* 0x300C */ + uint8_t clp_sl_end; /* 0x300D */ + uint8_t off_start; /* 0x300E */ + uint8_t rmp_en_start; /* 0x300F */ + uint8_t tx_start; /* 0x3010 */ + uint8_t tx_end; /* 0x3011 */ + uint8_t stx_width; /* 0x3012 */ + uint8_t reg_3152_reserved; /* 0x3152 */ + uint8_t reg_315A_reserved; /* 0x315A */ + uint8_t analogue_gain_code_global_msb; /* 0x0204 */ + uint8_t analogue_gain_code_global_lsb; /* 0x0205 */ + uint8_t fine_integration_time; /* 0x0200 */ + uint8_t coarse_integration_time; /* 0x0202 */ + uint32_t size_h; + uint32_t blk_l; + uint32_t size_w; + uint32_t blk_p; +}; + +struct reg_struct s5k3e2fx_reg_pat[2] = { + { /* Preview */ + 0x06, /* pre_pll_clk_div REG=0x0305 */ + 0x00, /* pll_multiplier_msb REG=0x0306 */ + 0x88, /* pll_multiplier_lsb REG=0x0307 */ + 0x0a, /* vt_pix_clk_div REG=0x0301 */ + 0x01, /* vt_sys_clk_div REG=0x0303 */ + 0x0a, /* op_pix_clk_div REG=0x0309 */ + 0x01, /* op_sys_clk_div REG=0x030B */ + 0x0a, /* ccp_data_format_msb REG=0x0112 */ + 0x0a, /* ccp_data_format_lsb REG=0x0113 */ + 0x05, /* x_output_size_msb REG=0x034C */ + 0x10, /* x_output_size_lsb REG=0x034D */ + 0x03, /* y_output_size_msb REG=0x034E */ + 0xcc, /* y_output_size_lsb REG=0x034F */ + + /* enable binning for preview */ + 0x01, /* x_even_inc REG=0x0381 */ + 0x01, /* x_odd_inc REG=0x0383 */ + 0x01, /* y_even_inc REG=0x0385 */ + 0x03, /* y_odd_inc REG=0x0387 */ + 0x06, /* binning_enable REG=0x3014 */ + + 0x03, /* frame_length_lines_msb REG=0x0340 */ + 0xde, /* frame_length_lines_lsb REG=0x0341 */ + 0x0a, /* line_length_pck_msb REG=0x0342 */ + 0xac, /* line_length_pck_lsb REG=0x0343 */ + 0x81, /* shade_clk_enable REG=0x30AC */ + 0x01, /* sel_ccp REG=0x30C4 */ + 0x04, /* vpix REG=0x3024 */ + 0x00, /* clamp_on REG=0x3015 */ + 0x02, /* offset REG=0x307E */ + 0x03, /* ld_start REG=0x3000 */ + 0x9c, /* ld_end REG=0x3001 */ + 0x02, /* sl_start REG=0x3002 */ + 0x9e, /* sl_end REG=0x3003 */ + 0x05, /* rx_start REG=0x3004 */ + 0x0f, /* s1_start REG=0x3005 */ + 0x24, /* s1_end REG=0x3006 */ + 0x7c, /* s1s_start REG=0x3007 */ + 0x9a, /* s1s_end REG=0x3008 */ + 0x10, /* s3_start REG=0x3009 */ + 0x14, /* s3_end REG=0x300A */ + 0x10, /* cmp_en_start REG=0x300B */ + 0x04, /* clp_sl_start REG=0x300C */ + 0x26, /* clp_sl_end REG=0x300D */ + 0x02, /* off_start REG=0x300E */ + 0x0e, /* rmp_en_start REG=0x300F */ + 0x30, /* tx_start REG=0x3010 */ + 0x4e, /* tx_end REG=0x3011 */ + 0x1E, /* stx_width REG=0x3012 */ + 0x08, /* reg_3152_reserved REG=0x3152 */ + 0x10, /* reg_315A_reserved REG=0x315A */ + 0x00, /* analogue_gain_code_global_msb REG=0x0204 */ + 0x80, /* analogue_gain_code_global_lsb REG=0x0205 */ + 0x02, /* fine_integration_time REG=0x0200 */ + 0x03, /* coarse_integration_time REG=0x0202 */ + 972, + 18, + 1296, + 1436 + }, + { /* Snapshot */ + 0x06, /* pre_pll_clk_div REG=0x0305 */ + 0x00, /* pll_multiplier_msb REG=0x0306 */ + 0x88, /* pll_multiplier_lsb REG=0x0307 */ + 0x0a, /* vt_pix_clk_div REG=0x0301 */ + 0x01, /* vt_sys_clk_div REG=0x0303 */ + 0x0a, /* op_pix_clk_div REG=0x0309 */ + 0x01, /* op_sys_clk_div REG=0x030B */ + 0x0a, /* ccp_data_format_msb REG=0x0112 */ + 0x0a, /* ccp_data_format_lsb REG=0x0113 */ + 0x0a, /* x_output_size_msb REG=0x034C */ + 0x30, /* x_output_size_lsb REG=0x034D */ + 0x07, /* y_output_size_msb REG=0x034E */ + 0xa8, /* y_output_size_lsb REG=0x034F */ + + /* disable binning for snapshot */ + 0x01, /* x_even_inc REG=0x0381 */ + 0x01, /* x_odd_inc REG=0x0383 */ + 0x01, /* y_even_inc REG=0x0385 */ + 0x01, /* y_odd_inc REG=0x0387 */ + 0x00, /* binning_enable REG=0x3014 */ + + 0x07, /* frame_length_lines_msb REG=0x0340 */ + 0xb6, /* frame_length_lines_lsb REG=0x0341 */ + 0x0a, /* line_length_pck_msb REG=0x0342 */ + 0xac, /* line_length_pck_lsb REG=0x0343 */ + 0x81, /* shade_clk_enable REG=0x30AC */ + 0x01, /* sel_ccp REG=0x30C4 */ + 0x04, /* vpix REG=0x3024 */ + 0x00, /* clamp_on REG=0x3015 */ + 0x02, /* offset REG=0x307E */ + 0x03, /* ld_start REG=0x3000 */ + 0x9c, /* ld_end REG=0x3001 */ + 0x02, /* sl_start REG=0x3002 */ + 0x9e, /* sl_end REG=0x3003 */ + 0x05, /* rx_start REG=0x3004 */ + 0x0f, /* s1_start REG=0x3005 */ + 0x24, /* s1_end REG=0x3006 */ + 0x7c, /* s1s_start REG=0x3007 */ + 0x9a, /* s1s_end REG=0x3008 */ + 0x10, /* s3_start REG=0x3009 */ + 0x14, /* s3_end REG=0x300A */ + 0x10, /* cmp_en_start REG=0x300B */ + 0x04, /* clp_sl_start REG=0x300C */ + 0x26, /* clp_sl_end REG=0x300D */ + 0x02, /* off_start REG=0x300E */ + 0x0e, /* rmp_en_start REG=0x300F */ + 0x30, /* tx_start REG=0x3010 */ + 0x4e, /* tx_end REG=0x3011 */ + 0x1E, /* stx_width REG=0x3012 */ + 0x08, /* reg_3152_reserved REG=0x3152 */ + 0x10, /* reg_315A_reserved REG=0x315A */ + 0x00, /* analogue_gain_code_global_msb REG=0x0204 */ + 0x80, /* analogue_gain_code_global_lsb REG=0x0205 */ + 0x02, /* fine_integration_time REG=0x0200 */ + 0x03, /* coarse_integration_time REG=0x0202 */ + 1960, + 14, + 2608, + 124 + } +}; + +struct s5k3e2fx_work { + struct work_struct work; +}; +static struct s5k3e2fx_work *s5k3e2fx_sensorw; +static struct i2c_client *s5k3e2fx_client; + +struct s5k3e2fx_ctrl { + const struct msm_camera_sensor_info *sensordata; + + int sensormode; + uint32_t fps_divider; /* init to 1 * 0x00000400 */ + uint32_t pict_fps_divider; /* init to 1 * 0x00000400 */ + + uint16_t curr_lens_pos; + uint16_t init_curr_lens_pos; + uint16_t my_reg_gain; + uint32_t my_reg_line_count; + + enum msm_s_resolution prev_res; + enum msm_s_resolution pict_res; + enum msm_s_resolution curr_res; + enum msm_s_test_mode set_test; +}; + +struct s5k3e2fx_i2c_reg_conf { + unsigned short waddr; + unsigned char bdata; +}; + +static struct s5k3e2fx_ctrl *s5k3e2fx_ctrl; +static DECLARE_WAIT_QUEUE_HEAD(s5k3e2fx_wait_queue); +DECLARE_MUTEX(s5k3e2fx_sem); + +static int s5k3e2fx_i2c_rxdata(unsigned short saddr, unsigned char *rxdata, + int length) +{ + struct i2c_msg msgs[] = { + { + .addr = saddr, + .flags = 0, + .len = 2, + .buf = rxdata, + }, + { + .addr = saddr, + .flags = I2C_M_RD, + .len = length, + .buf = rxdata, + }, + }; + + if (i2c_transfer(s5k3e2fx_client->adapter, msgs, 2) < 0) { + CDBG("s5k3e2fx_i2c_rxdata failed!\n"); + return -EIO; + } + + return 0; +} + +static int32_t s5k3e2fx_i2c_txdata(unsigned short saddr, + unsigned char *txdata, int length) +{ + struct i2c_msg msg[] = { + { + .addr = saddr, + .flags = 0, + .len = length, + .buf = txdata, + }, + }; + + if (i2c_transfer(s5k3e2fx_client->adapter, msg, 1) < 0) { + CDBG("s5k3e2fx_i2c_txdata failed\n"); + return -EIO; + } + + return 0; +} + +static int32_t s5k3e2fx_i2c_write_b(unsigned short saddr, unsigned short waddr, + unsigned char bdata) +{ + int32_t rc = -EIO; + unsigned char buf[4]; + + memset(buf, 0, sizeof(buf)); + buf[0] = (waddr & 0xFF00)>>8; + buf[1] = (waddr & 0x00FF); + buf[2] = bdata; + + rc = s5k3e2fx_i2c_txdata(saddr, buf, 3); + + if (rc < 0) + CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n", + waddr, bdata); + + return rc; +} + +static int32_t s5k3e2fx_i2c_write_table( + struct s5k3e2fx_i2c_reg_conf *reg_cfg_tbl, int num) +{ + int i; + int32_t rc = -EIO; + for (i = 0; i < num; i++) { + if (rc < 0) + break; + reg_cfg_tbl++; + } + + return rc; +} + +static int32_t s5k3e2fx_i2c_read_w(unsigned short saddr, unsigned short raddr, + unsigned short *rdata) +{ + int32_t rc = 0; + unsigned char buf[4]; + + if (!rdata) + return -EIO; + + memset(buf, 0, sizeof(buf)); + + buf[0] = (raddr & 0xFF00)>>8; + buf[1] = (raddr & 0x00FF); + + rc = s5k3e2fx_i2c_rxdata(saddr, buf, 2); + if (rc < 0) + return rc; + + *rdata = buf[0] << 8 | buf[1]; + + if (rc < 0) + CDBG("s5k3e2fx_i2c_read failed!\n"); + + return rc; +} + +static int s5k3e2fx_probe_init_done(const struct msm_camera_sensor_info *data) +{ + gpio_direction_output(data->sensor_reset, 0); + gpio_free(data->sensor_reset); + return 0; +} + +static int s5k3e2fx_probe_init_sensor(const struct msm_camera_sensor_info *data) +{ + int32_t rc; + uint16_t chipid = 0; + + rc = gpio_request(data->sensor_reset, "s5k3e2fx"); + if (!rc) + gpio_direction_output(data->sensor_reset, 1); + else + goto init_probe_done; + + mdelay(20); + + CDBG("s5k3e2fx_sensor_init(): reseting sensor.\n"); + + rc = s5k3e2fx_i2c_read_w(s5k3e2fx_client->addr, + S5K3E2FX_REG_MODEL_ID, &chipid); + if (rc < 0) + goto init_probe_fail; + + if (chipid != S5K3E2FX_MODEL_ID) { + CDBG("S5K3E2FX wrong model_id = 0x%x\n", chipid); + rc = -ENODEV; + goto init_probe_fail; + } + + goto init_probe_done; + +init_probe_fail: + s5k3e2fx_probe_init_done(data); +init_probe_done: + return rc; +} + +static int s5k3e2fx_init_client(struct i2c_client *client) +{ + /* Initialize the MSM_CAMI2C Chip */ + init_waitqueue_head(&s5k3e2fx_wait_queue); + return 0; +} + +static const struct i2c_device_id s5k3e2fx_i2c_id[] = { + { "s5k3e2fx", 0}, + { } +}; + +static int s5k3e2fx_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int rc = 0; + CDBG("s5k3e2fx_probe called!\n"); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + CDBG("i2c_check_functionality failed\n"); + goto probe_failure; + } + + s5k3e2fx_sensorw = kzalloc(sizeof(struct s5k3e2fx_work), GFP_KERNEL); + if (!s5k3e2fx_sensorw) { + CDBG("kzalloc failed.\n"); + rc = -ENOMEM; + goto probe_failure; + } + + i2c_set_clientdata(client, s5k3e2fx_sensorw); + s5k3e2fx_init_client(client); + s5k3e2fx_client = client; + + mdelay(50); + + CDBG("s5k3e2fx_probe successed! rc = %d\n", rc); + return 0; + +probe_failure: + CDBG("s5k3e2fx_probe failed! rc = %d\n", rc); + return rc; +} + +static struct i2c_driver s5k3e2fx_i2c_driver = { + .id_table = s5k3e2fx_i2c_id, + .probe = s5k3e2fx_i2c_probe, + .remove = __exit_p(s5k3e2fx_i2c_remove), + .driver = { + .name = "s5k3e2fx", + }, +}; + +static int32_t s5k3e2fx_test(enum msm_s_test_mode mo) +{ + int32_t rc = 0; + + if (mo == S_TEST_OFF) + rc = 0; + else + rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, + REG_TEST_PATTERN_MODE, (uint16_t)mo); + + return rc; +} + +static int32_t s5k3e2fx_setting(enum msm_s_reg_update rupdate, + enum msm_s_setting rt) +{ + int32_t rc = 0; + uint16_t num_lperf; + + switch (rupdate) { + case S_UPDATE_PERIODIC: + if (rt == S_RES_PREVIEW || rt == S_RES_CAPTURE) { + + struct s5k3e2fx_i2c_reg_conf tbl_1[] = { + {REG_CCP_DATA_FORMAT_MSB, s5k3e2fx_reg_pat[rt].ccp_data_format_msb}, + {REG_CCP_DATA_FORMAT_LSB, s5k3e2fx_reg_pat[rt].ccp_data_format_lsb}, + {REG_X_OUTPUT_SIZE_MSB, s5k3e2fx_reg_pat[rt].x_output_size_msb}, + {REG_X_OUTPUT_SIZE_LSB, s5k3e2fx_reg_pat[rt].x_output_size_lsb}, + {REG_Y_OUTPUT_SIZE_MSB, s5k3e2fx_reg_pat[rt].y_output_size_msb}, + {REG_Y_OUTPUT_SIZE_LSB, s5k3e2fx_reg_pat[rt].y_output_size_lsb}, + {REG_X_EVEN_INC, s5k3e2fx_reg_pat[rt].x_even_inc}, + {REG_X_ODD_INC, s5k3e2fx_reg_pat[rt].x_odd_inc}, + {REG_Y_EVEN_INC, s5k3e2fx_reg_pat[rt].y_even_inc}, + {REG_Y_ODD_INC, s5k3e2fx_reg_pat[rt].y_odd_inc}, + {REG_BINNING_ENABLE, s5k3e2fx_reg_pat[rt].binning_enable}, + }; + + struct s5k3e2fx_i2c_reg_conf tbl_2[] = { + {REG_FRAME_LENGTH_LINES_MSB, 0}, + {REG_FRAME_LENGTH_LINES_LSB, 0}, + {REG_LINE_LENGTH_PCK_MSB, s5k3e2fx_reg_pat[rt].line_length_pck_msb}, + {REG_LINE_LENGTH_PCK_LSB, s5k3e2fx_reg_pat[rt].line_length_pck_lsb}, + {REG_SHADE_CLK_ENABLE, s5k3e2fx_reg_pat[rt].shade_clk_enable}, + {REG_SEL_CCP, s5k3e2fx_reg_pat[rt].sel_ccp}, + {REG_VPIX, s5k3e2fx_reg_pat[rt].vpix}, + {REG_CLAMP_ON, s5k3e2fx_reg_pat[rt].clamp_on}, + {REG_OFFSET, s5k3e2fx_reg_pat[rt].offset}, + {REG_LD_START, s5k3e2fx_reg_pat[rt].ld_start}, + {REG_LD_END, s5k3e2fx_reg_pat[rt].ld_end}, + {REG_SL_START, s5k3e2fx_reg_pat[rt].sl_start}, + {REG_SL_END, s5k3e2fx_reg_pat[rt].sl_end}, + {REG_RX_START, s5k3e2fx_reg_pat[rt].rx_start}, + {REG_S1_START, s5k3e2fx_reg_pat[rt].s1_start}, + {REG_S1_END, s5k3e2fx_reg_pat[rt].s1_end}, + {REG_S1S_START, s5k3e2fx_reg_pat[rt].s1s_start}, + {REG_S1S_END, s5k3e2fx_reg_pat[rt].s1s_end}, + {REG_S3_START, s5k3e2fx_reg_pat[rt].s3_start}, + {REG_S3_END, s5k3e2fx_reg_pat[rt].s3_end}, + {REG_CMP_EN_START, s5k3e2fx_reg_pat[rt].cmp_en_start}, + {REG_CLP_SL_START, s5k3e2fx_reg_pat[rt].clp_sl_start}, + {REG_CLP_SL_END, s5k3e2fx_reg_pat[rt].clp_sl_end}, + {REG_OFF_START, s5k3e2fx_reg_pat[rt].off_start}, + {REG_RMP_EN_START, s5k3e2fx_reg_pat[rt].rmp_en_start}, + {REG_TX_START, s5k3e2fx_reg_pat[rt].tx_start}, + {REG_TX_END, s5k3e2fx_reg_pat[rt].tx_end}, + {REG_STX_WIDTH, s5k3e2fx_reg_pat[rt].stx_width}, + {REG_3152_RESERVED, s5k3e2fx_reg_pat[rt].reg_3152_reserved}, + {REG_315A_RESERVED, s5k3e2fx_reg_pat[rt].reg_315A_reserved}, + {REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB, s5k3e2fx_reg_pat[rt].analogue_gain_code_global_msb}, + {REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB, s5k3e2fx_reg_pat[rt].analogue_gain_code_global_lsb}, + {REG_FINE_INTEGRATION_TIME, s5k3e2fx_reg_pat[rt].fine_integration_time}, + {REG_COARSE_INTEGRATION_TIME, s5k3e2fx_reg_pat[rt].coarse_integration_time}, + {S5K3E2FX_REG_MODE_SELECT, S5K3E2FX_MODE_SELECT_STREAM}, + }; + + rc = s5k3e2fx_i2c_write_table(&tbl_1[0], + ARRAY_SIZE(tbl_1)); + if (rc < 0) + return rc; + + num_lperf = + (uint16_t)((s5k3e2fx_reg_pat[rt].frame_length_lines_msb << 8) & 0xFF00) + + s5k3e2fx_reg_pat[rt].frame_length_lines_lsb; + + num_lperf = num_lperf * s5k3e2fx_ctrl->fps_divider / 0x0400; + + tbl_2[0] = (struct s5k3e2fx_i2c_reg_conf) {REG_FRAME_LENGTH_LINES_MSB, (num_lperf & 0xFF00) >> 8}; + tbl_2[1] = (struct s5k3e2fx_i2c_reg_conf) {REG_FRAME_LENGTH_LINES_LSB, (num_lperf & 0x00FF)}; + + rc = s5k3e2fx_i2c_write_table(&tbl_2[0], + ARRAY_SIZE(tbl_2)); + if (rc < 0) + return rc; + + mdelay(5); + + rc = s5k3e2fx_test(s5k3e2fx_ctrl->set_test); + if (rc < 0) + return rc; + } + break; /* UPDATE_PERIODIC */ + + case S_REG_INIT: + if (rt == S_RES_PREVIEW || rt == S_RES_CAPTURE) { + + struct s5k3e2fx_i2c_reg_conf tbl_3[] = { + {S5K3E2FX_REG_SOFTWARE_RESET, S5K3E2FX_SOFTWARE_RESET}, + {S5K3E2FX_REG_MODE_SELECT, S5K3E2FX_MODE_SELECT_SW_STANDBY}, + /* PLL setting */ + {REG_PRE_PLL_CLK_DIV, s5k3e2fx_reg_pat[rt].pre_pll_clk_div}, + {REG_PLL_MULTIPLIER_MSB, s5k3e2fx_reg_pat[rt].pll_multiplier_msb}, + {REG_PLL_MULTIPLIER_LSB, s5k3e2fx_reg_pat[rt].pll_multiplier_lsb}, + {REG_VT_PIX_CLK_DIV, s5k3e2fx_reg_pat[rt].vt_pix_clk_div}, + {REG_VT_SYS_CLK_DIV, s5k3e2fx_reg_pat[rt].vt_sys_clk_div}, + {REG_OP_PIX_CLK_DIV, s5k3e2fx_reg_pat[rt].op_pix_clk_div}, + {REG_OP_SYS_CLK_DIV, s5k3e2fx_reg_pat[rt].op_sys_clk_div}, + /*Data Format */ + {REG_CCP_DATA_FORMAT_MSB, s5k3e2fx_reg_pat[rt].ccp_data_format_msb}, + {REG_CCP_DATA_FORMAT_LSB, s5k3e2fx_reg_pat[rt].ccp_data_format_lsb}, + /*Output Size */ + {REG_X_OUTPUT_SIZE_MSB, s5k3e2fx_reg_pat[rt].x_output_size_msb}, + {REG_X_OUTPUT_SIZE_LSB, s5k3e2fx_reg_pat[rt].x_output_size_lsb}, + {REG_Y_OUTPUT_SIZE_MSB, s5k3e2fx_reg_pat[rt].y_output_size_msb}, + {REG_Y_OUTPUT_SIZE_LSB, s5k3e2fx_reg_pat[rt].y_output_size_lsb}, + /* Binning */ + {REG_X_EVEN_INC, s5k3e2fx_reg_pat[rt].x_even_inc}, + {REG_X_ODD_INC, s5k3e2fx_reg_pat[rt].x_odd_inc }, + {REG_Y_EVEN_INC, s5k3e2fx_reg_pat[rt].y_even_inc}, + {REG_Y_ODD_INC, s5k3e2fx_reg_pat[rt].y_odd_inc}, + {REG_BINNING_ENABLE, s5k3e2fx_reg_pat[rt].binning_enable}, + /* Frame format */ + {REG_FRAME_LENGTH_LINES_MSB, s5k3e2fx_reg_pat[rt].frame_length_lines_msb}, + {REG_FRAME_LENGTH_LINES_LSB, s5k3e2fx_reg_pat[rt].frame_length_lines_lsb}, + {REG_LINE_LENGTH_PCK_MSB, s5k3e2fx_reg_pat[rt].line_length_pck_msb}, + {REG_LINE_LENGTH_PCK_LSB, s5k3e2fx_reg_pat[rt].line_length_pck_lsb}, + /* MSR setting */ + {REG_SHADE_CLK_ENABLE, s5k3e2fx_reg_pat[rt].shade_clk_enable}, + {REG_SEL_CCP, s5k3e2fx_reg_pat[rt].sel_ccp}, + {REG_VPIX, s5k3e2fx_reg_pat[rt].vpix}, + {REG_CLAMP_ON, s5k3e2fx_reg_pat[rt].clamp_on}, + {REG_OFFSET, s5k3e2fx_reg_pat[rt].offset}, + /* CDS timing setting */ + {REG_LD_START, s5k3e2fx_reg_pat[rt].ld_start}, + {REG_LD_END, s5k3e2fx_reg_pat[rt].ld_end}, + {REG_SL_START, s5k3e2fx_reg_pat[rt].sl_start}, + {REG_SL_END, s5k3e2fx_reg_pat[rt].sl_end}, + {REG_RX_START, s5k3e2fx_reg_pat[rt].rx_start}, + {REG_S1_START, s5k3e2fx_reg_pat[rt].s1_start}, + {REG_S1_END, s5k3e2fx_reg_pat[rt].s1_end}, + {REG_S1S_START, s5k3e2fx_reg_pat[rt].s1s_start}, + {REG_S1S_END, s5k3e2fx_reg_pat[rt].s1s_end}, + {REG_S3_START, s5k3e2fx_reg_pat[rt].s3_start}, + {REG_S3_END, s5k3e2fx_reg_pat[rt].s3_end}, + {REG_CMP_EN_START, s5k3e2fx_reg_pat[rt].cmp_en_start}, + {REG_CLP_SL_START, s5k3e2fx_reg_pat[rt].clp_sl_start}, + {REG_CLP_SL_END, s5k3e2fx_reg_pat[rt].clp_sl_end}, + {REG_OFF_START, s5k3e2fx_reg_pat[rt].off_start}, + {REG_RMP_EN_START, s5k3e2fx_reg_pat[rt].rmp_en_start}, + {REG_TX_START, s5k3e2fx_reg_pat[rt].tx_start}, + {REG_TX_END, s5k3e2fx_reg_pat[rt].tx_end}, + {REG_STX_WIDTH, s5k3e2fx_reg_pat[rt].stx_width}, + {REG_3152_RESERVED, s5k3e2fx_reg_pat[rt].reg_3152_reserved}, + {REG_315A_RESERVED, s5k3e2fx_reg_pat[rt].reg_315A_reserved}, + {REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB, s5k3e2fx_reg_pat[rt].analogue_gain_code_global_msb}, + {REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB, s5k3e2fx_reg_pat[rt].analogue_gain_code_global_lsb}, + {REG_FINE_INTEGRATION_TIME, s5k3e2fx_reg_pat[rt].fine_integration_time}, + {REG_COARSE_INTEGRATION_TIME, s5k3e2fx_reg_pat[rt].coarse_integration_time}, + {S5K3E2FX_REG_MODE_SELECT, S5K3E2FX_MODE_SELECT_STREAM}, + }; + + /* reset fps_divider */ + s5k3e2fx_ctrl->fps_divider = 1 * 0x0400; + rc = s5k3e2fx_i2c_write_table(&tbl_3[0], + ARRAY_SIZE(tbl_3)); + if (rc < 0) + return rc; + } + break; /* case REG_INIT: */ + + default: + rc = -EINVAL; + break; + } /* switch (rupdate) */ + + return rc; +} + +static int s5k3e2fx_sensor_open_init(const struct msm_camera_sensor_info *data) +{ + int32_t rc; + + s5k3e2fx_ctrl = kzalloc(sizeof(struct s5k3e2fx_ctrl), GFP_KERNEL); + if (!s5k3e2fx_ctrl) { + CDBG("s5k3e2fx_init failed!\n"); + rc = -ENOMEM; + goto init_done; + } + + s5k3e2fx_ctrl->fps_divider = 1 * 0x00000400; + s5k3e2fx_ctrl->pict_fps_divider = 1 * 0x00000400; + s5k3e2fx_ctrl->set_test = S_TEST_OFF; + s5k3e2fx_ctrl->prev_res = S_QTR_SIZE; + s5k3e2fx_ctrl->pict_res = S_FULL_SIZE; + + if (data) + s5k3e2fx_ctrl->sensordata = data; + + /* enable mclk first */ + msm_camio_clk_rate_set(24000000); + mdelay(20); + + msm_camio_camif_pad_reg_reset(); + mdelay(20); + + rc = s5k3e2fx_probe_init_sensor(data); + if (rc < 0) + goto init_fail1; + + if (s5k3e2fx_ctrl->prev_res == S_QTR_SIZE) + rc = s5k3e2fx_setting(S_REG_INIT, S_RES_PREVIEW); + else + rc = s5k3e2fx_setting(S_REG_INIT, S_RES_CAPTURE); + + if (rc < 0) { + CDBG("s5k3e2fx_setting failed. rc = %d\n", rc); + goto init_fail1; + } + + /* initialize AF */ + rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3146, 0x3A); + if (rc < 0) + goto init_fail1; + + rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3130, 0x03); + if (rc < 0) + goto init_fail1; + + goto init_done; + +init_fail1: + s5k3e2fx_probe_init_done(data); + kfree(s5k3e2fx_ctrl); +init_done: + return rc; +} + +static int32_t s5k3e2fx_power_down(void) +{ + int32_t rc = 0; + return rc; +} + +static int s5k3e2fx_sensor_release(void) +{ + int rc = -EBADF; + + down(&s5k3e2fx_sem); + + s5k3e2fx_power_down(); + + gpio_direction_output(s5k3e2fx_ctrl->sensordata->sensor_reset, + 0); + gpio_free(s5k3e2fx_ctrl->sensordata->sensor_reset); + + kfree(s5k3e2fx_ctrl); + s5k3e2fx_ctrl = NULL; + + CDBG("s5k3e2fx_release completed\n"); + + up(&s5k3e2fx_sem); + return rc; +} + +static void s5k3e2fx_get_pict_fps(uint16_t fps, uint16_t *pfps) +{ + /* input fps is preview fps in Q8 format */ + uint32_t divider; /* Q10 */ + + divider = (uint32_t) + ((s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h + + s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l) * + (s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w + + s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p)) * 0x00000400 / + ((s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h + + s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l) * + (s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w + + s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p)); + + /* Verify PCLK settings and frame sizes. */ + *pfps = (uint16_t)(fps * divider / 0x00000400); +} + +static uint16_t s5k3e2fx_get_prev_lines_pf(void) +{ + return (s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h + + s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l); +} + +static uint16_t s5k3e2fx_get_prev_pixels_pl(void) +{ + return s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w + + s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p; +} + +static uint16_t s5k3e2fx_get_pict_lines_pf(void) +{ + return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h + + s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l; +} + +static uint16_t s5k3e2fx_get_pict_pixels_pl(void) +{ + return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w + + s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p; +} + +static uint32_t s5k3e2fx_get_pict_max_exp_lc(void) +{ + uint32_t snapshot_lines_per_frame; + + if (s5k3e2fx_ctrl->pict_res == S_QTR_SIZE) + snapshot_lines_per_frame = + s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h + + s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l; + else + snapshot_lines_per_frame = 3961 * 3; + + return snapshot_lines_per_frame; +} + +static int32_t s5k3e2fx_set_fps(struct fps_cfg *fps) +{ + /* input is new fps in Q10 format */ + int32_t rc = 0; + + s5k3e2fx_ctrl->fps_divider = fps->fps_div; + + rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, + REG_FRAME_LENGTH_LINES_MSB, + (((s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h + + s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l) * + s5k3e2fx_ctrl->fps_divider / 0x400) & 0xFF00) >> 8); + if (rc < 0) + goto set_fps_done; + + rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, + REG_FRAME_LENGTH_LINES_LSB, + (((s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h + + s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l) * + s5k3e2fx_ctrl->fps_divider / 0x400) & 0xFF00)); + +set_fps_done: + return rc; +} + +static int32_t s5k3e2fx_write_exp_gain(uint16_t gain, uint32_t line) +{ + int32_t rc = 0; + + uint16_t max_legal_gain = 0x0200; + uint32_t ll_ratio; /* Q10 */ + uint16_t ll_pck, fl_lines; + uint16_t offset = 4; + uint8_t gain_msb, gain_lsb; + uint8_t intg_t_msb, intg_t_lsb; + uint8_t ll_pck_msb, ll_pck_lsb, tmp; + + struct s5k3e2fx_i2c_reg_conf tbl[2]; + + CDBG("Line:%d s5k3e2fx_write_exp_gain \n", __LINE__); + + if (s5k3e2fx_ctrl->sensormode == SENSOR_PREVIEW_MODE) { + + s5k3e2fx_ctrl->my_reg_gain = gain; + s5k3e2fx_ctrl->my_reg_line_count = (uint16_t)line; + + fl_lines = s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h + + s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l; + + ll_pck = s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w + + s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p; + + } else { + + fl_lines = s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h + + s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l; + + ll_pck = s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w + + s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p; + } + + if (gain > max_legal_gain) + gain = max_legal_gain; + + /* in Q10 */ + line = (line * s5k3e2fx_ctrl->fps_divider); + + if (fl_lines < (line / 0x400)) + ll_ratio = (line / (fl_lines - offset)); + else + ll_ratio = 0x400; + + /* update gain registers */ + gain_msb = (gain & 0xFF00) >> 8; + gain_lsb = gain & 0x00FF; + tbl[0].waddr = REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB; + tbl[0].bdata = gain_msb; + tbl[1].waddr = REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB; + tbl[1].bdata = gain_lsb; + rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl)); + if (rc < 0) + goto write_gain_done; + + ll_pck = ll_pck * ll_ratio; + ll_pck_msb = ((ll_pck / 0x400) & 0xFF00) >> 8; + ll_pck_lsb = (ll_pck / 0x400) & 0x00FF; + tbl[0].waddr = REG_LINE_LENGTH_PCK_MSB; + tbl[0].bdata = s5k3e2fx_reg_pat[S_RES_PREVIEW].line_length_pck_msb; + tbl[1].waddr = REG_LINE_LENGTH_PCK_LSB; + tbl[1].bdata = s5k3e2fx_reg_pat[S_RES_PREVIEW].line_length_pck_lsb; + rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl)); + if (rc < 0) + goto write_gain_done; + + tmp = (ll_pck * 0x400) / ll_ratio; + intg_t_msb = (tmp & 0xFF00) >> 8; + intg_t_lsb = (tmp & 0x00FF); + tbl[0].waddr = REG_COARSE_INTEGRATION_TIME; + tbl[0].bdata = intg_t_msb; + tbl[1].waddr = REG_COARSE_INTEGRATION_TIME_LSB; + tbl[1].bdata = intg_t_lsb; + rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl)); + +write_gain_done: + return rc; +} + +static int32_t s5k3e2fx_set_pict_exp_gain(uint16_t gain, uint32_t line) +{ + int32_t rc = 0; + + CDBG("Line:%d s5k3e2fx_set_pict_exp_gain \n", __LINE__); + + rc = + s5k3e2fx_write_exp_gain(gain, line); + + return rc; +} + +static int32_t s5k3e2fx_video_config(int mode, int res) +{ + int32_t rc; + + switch (res) { + case S_QTR_SIZE: + rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_PREVIEW); + if (rc < 0) + return rc; + + CDBG("s5k3e2fx sensor configuration done!\n"); + break; + + case S_FULL_SIZE: + rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE); + if (rc < 0) + return rc; + + break; + + default: + return 0; + } /* switch */ + + s5k3e2fx_ctrl->prev_res = res; + s5k3e2fx_ctrl->curr_res = res; + s5k3e2fx_ctrl->sensormode = mode; + + rc = + s5k3e2fx_write_exp_gain(s5k3e2fx_ctrl->my_reg_gain, + s5k3e2fx_ctrl->my_reg_line_count); + + return rc; +} + +static int32_t s5k3e2fx_snapshot_config(int mode) +{ + int32_t rc = 0; + + rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE); + if (rc < 0) + return rc; + + s5k3e2fx_ctrl->curr_res = s5k3e2fx_ctrl->pict_res; + s5k3e2fx_ctrl->sensormode = mode; + + return rc; +} + +static int32_t s5k3e2fx_raw_snapshot_config(int mode) +{ + int32_t rc = 0; + + rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE); + if (rc < 0) + return rc; + + s5k3e2fx_ctrl->curr_res = s5k3e2fx_ctrl->pict_res; + s5k3e2fx_ctrl->sensormode = mode; + + return rc; +} + +static int32_t s5k3e2fx_set_sensor_mode(int mode, int res) +{ + int32_t rc = 0; + + switch (mode) { + case SENSOR_PREVIEW_MODE: + rc = s5k3e2fx_video_config(mode, res); + break; + + case SENSOR_SNAPSHOT_MODE: + rc = s5k3e2fx_snapshot_config(mode); + break; + + case SENSOR_RAW_SNAPSHOT_MODE: + rc = s5k3e2fx_raw_snapshot_config(mode); + break; + + default: + rc = -EINVAL; + break; + } + + return rc; +} + +static int32_t s5k3e2fx_set_default_focus(void) +{ + int32_t rc = 0; + + rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, + 0x3131, 0); + if (rc < 0) + return rc; + + rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, + 0x3132, 0); + if (rc < 0) + return rc; + + s5k3e2fx_ctrl->curr_lens_pos = 0; + + return rc; +} + +static int32_t s5k3e2fx_move_focus(int direction, int32_t num_steps) +{ + int32_t rc = 0; + int32_t i; + int16_t step_direction; + int16_t actual_step; + int16_t next_pos, pos_offset; + int16_t init_code = 50; + uint8_t next_pos_msb, next_pos_lsb; + int16_t s_move[5]; + uint32_t gain; /* Q10 format */ + + if (direction == MOVE_NEAR) + step_direction = 20; + else if (direction == MOVE_FAR) + step_direction = -20; + else { + CDBG("s5k3e2fx_move_focus failed at line %d ...\n", __LINE__); + return -EINVAL; + } + + actual_step = step_direction * (int16_t)num_steps; + pos_offset = init_code + s5k3e2fx_ctrl->curr_lens_pos; + gain = ((actual_step << 10) / 5) >> 10; + + for (i = 0; i <= 4; i++) + s_move[i] = gain; + + /* Ring Damping Code */ + for (i = 0; i <= 4; i++) { + next_pos = (int16_t)(pos_offset + s_move[i]); + + if (next_pos > (738 + init_code)) + next_pos = 738 + init_code; + else if (next_pos < 0) + next_pos = 0; + + CDBG("next_position in damping mode = %d\n", next_pos); + /* Writing the Values to the actuator */ + if (next_pos == init_code) + next_pos = 0x00; + + next_pos_msb = next_pos >> 8; + next_pos_lsb = next_pos & 0x00FF; + + rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3131, next_pos_msb); + if (rc < 0) + break; + + rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3132, next_pos_lsb); + if (rc < 0) + break; + + pos_offset = next_pos; + s5k3e2fx_ctrl->curr_lens_pos = pos_offset - init_code; + if (i < 4) + mdelay(3); + } + + return rc; +} + +static int s5k3e2fx_sensor_config(void __user *argp) +{ + struct sensor_cfg_data cdata; + long rc = 0; + + if (copy_from_user(&cdata, + (void *)argp, + sizeof(struct sensor_cfg_data))) + return -EFAULT; + + down(&s5k3e2fx_sem); + + CDBG("%s: cfgtype = %d\n", __func__, cdata.cfgtype); + switch (cdata.cfgtype) { + case CFG_GET_PICT_FPS: + s5k3e2fx_get_pict_fps(cdata.cfg.gfps.prevfps, + &(cdata.cfg.gfps.pictfps)); + + if (copy_to_user((void *)argp, &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_GET_PREV_L_PF: + cdata.cfg.prevl_pf = s5k3e2fx_get_prev_lines_pf(); + + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_GET_PREV_P_PL: + cdata.cfg.prevp_pl = s5k3e2fx_get_prev_pixels_pl(); + + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_GET_PICT_L_PF: + cdata.cfg.pictl_pf = s5k3e2fx_get_pict_lines_pf(); + + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_GET_PICT_P_PL: + cdata.cfg.pictp_pl = s5k3e2fx_get_pict_pixels_pl(); + + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_GET_PICT_MAX_EXP_LC: + cdata.cfg.pict_max_exp_lc = + s5k3e2fx_get_pict_max_exp_lc(); + + if (copy_to_user((void *)argp, + &cdata, + sizeof(struct sensor_cfg_data))) + rc = -EFAULT; + break; + + case CFG_SET_FPS: + case CFG_SET_PICT_FPS: + rc = s5k3e2fx_set_fps(&(cdata.cfg.fps)); + break; + + case CFG_SET_EXP_GAIN: + rc = + s5k3e2fx_write_exp_gain(cdata.cfg.exp_gain.gain, + cdata.cfg.exp_gain.line); + break; + + case CFG_SET_PICT_EXP_GAIN: + CDBG("Line:%d CFG_SET_PICT_EXP_GAIN \n", __LINE__); + rc = + s5k3e2fx_set_pict_exp_gain( + cdata.cfg.exp_gain.gain, + cdata.cfg.exp_gain.line); + break; + + case CFG_SET_MODE: + rc = + s5k3e2fx_set_sensor_mode( + cdata.mode, cdata.rs); + break; + + case CFG_PWR_DOWN: + rc = s5k3e2fx_power_down(); + break; + + case CFG_MOVE_FOCUS: + rc = + s5k3e2fx_move_focus( + cdata.cfg.focus.dir, + cdata.cfg.focus.steps); + break; + + case CFG_SET_DEFAULT_FOCUS: + rc = + s5k3e2fx_set_default_focus(); + break; + + case CFG_GET_AF_MAX_STEPS: + case CFG_SET_EFFECT: + case CFG_SET_LENS_SHADING: + default: + rc = -EINVAL; + break; + } + + up(&s5k3e2fx_sem); + return rc; +} + +static int s5k3e2fx_sensor_probe(const struct msm_camera_sensor_info *info, + struct msm_sensor_ctrl *s) +{ + int rc = 0; + + rc = i2c_add_driver(&s5k3e2fx_i2c_driver); + if (rc < 0 || s5k3e2fx_client == NULL) { + rc = -ENOTSUPP; + goto probe_fail; + } + + msm_camio_clk_rate_set(24000000); + mdelay(20); + + rc = s5k3e2fx_probe_init_sensor(info); + if (rc < 0) + goto probe_fail; + + s->s_init = s5k3e2fx_sensor_open_init; + s->s_release = s5k3e2fx_sensor_release; + s->s_config = s5k3e2fx_sensor_config; + s5k3e2fx_probe_init_done(info); + + return rc; + +probe_fail: + CDBG("SENSOR PROBE FAILS!\n"); + return rc; +} + +static int __s5k3e2fx_probe(struct platform_device *pdev) +{ + return msm_camera_drv_start(pdev, s5k3e2fx_sensor_probe); +} + +static struct platform_driver msm_camera_driver = { + .probe = __s5k3e2fx_probe, + .driver = { + .name = "msm_camera_s5k3e2fx", + .owner = THIS_MODULE, + }, +}; + +static int __init s5k3e2fx_init(void) +{ + return platform_driver_register(&msm_camera_driver); +} + +module_init(s5k3e2fx_init); + diff --git a/trunk/drivers/staging/dream/camera/s5k3e2fx.h b/trunk/drivers/staging/dream/camera/s5k3e2fx.h new file mode 100644 index 000000000000..69bc75084457 --- /dev/null +++ b/trunk/drivers/staging/dream/camera/s5k3e2fx.h @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ + +#ifndef CAMSENSOR_S5K3E2FX +#define CAMSENSOR_S5K3E2FX + +#include +#endif /* CAMSENSOR_S5K3E2FX */ diff --git a/trunk/drivers/staging/dream/generic_gpio.c b/trunk/drivers/staging/dream/generic_gpio.c new file mode 100644 index 000000000000..fe24d38345d0 --- /dev/null +++ b/trunk/drivers/staging/dream/generic_gpio.c @@ -0,0 +1,274 @@ +/* arch/arm/mach-msm/generic_gpio.c + * + * Copyright (C) 2007 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include "gpio_chip.h" + +#define GPIO_NUM_TO_CHIP_INDEX(gpio) ((gpio)>>5) + +struct gpio_state { + unsigned long flags; + int refcount; +}; + +static DEFINE_SPINLOCK(gpio_chips_lock); +static LIST_HEAD(gpio_chip_list); +static struct gpio_chip **gpio_chip_array; +static unsigned long gpio_chip_array_size; + +int register_gpio_chip(struct gpio_chip *new_gpio_chip) +{ + int err = 0; + struct gpio_chip *gpio_chip; + int i; + unsigned long irq_flags; + unsigned int chip_array_start_index, chip_array_end_index; + + new_gpio_chip->state = kzalloc((new_gpio_chip->end + 1 - new_gpio_chip->start) * sizeof(new_gpio_chip->state[0]), GFP_KERNEL); + if (new_gpio_chip->state == NULL) { + printk(KERN_ERR "register_gpio_chip: failed to allocate state\n"); + return -ENOMEM; + } + + spin_lock_irqsave(&gpio_chips_lock, irq_flags); + chip_array_start_index = GPIO_NUM_TO_CHIP_INDEX(new_gpio_chip->start); + chip_array_end_index = GPIO_NUM_TO_CHIP_INDEX(new_gpio_chip->end); + if (chip_array_end_index >= gpio_chip_array_size) { + struct gpio_chip **new_gpio_chip_array; + unsigned long new_gpio_chip_array_size = chip_array_end_index + 1; + + new_gpio_chip_array = kmalloc(new_gpio_chip_array_size * sizeof(new_gpio_chip_array[0]), GFP_ATOMIC); + if (new_gpio_chip_array == NULL) { + printk(KERN_ERR "register_gpio_chip: failed to allocate array\n"); + err = -ENOMEM; + goto failed; + } + for (i = 0; i < gpio_chip_array_size; i++) + new_gpio_chip_array[i] = gpio_chip_array[i]; + for (i = gpio_chip_array_size; i < new_gpio_chip_array_size; i++) + new_gpio_chip_array[i] = NULL; + gpio_chip_array = new_gpio_chip_array; + gpio_chip_array_size = new_gpio_chip_array_size; + } + list_for_each_entry(gpio_chip, &gpio_chip_list, list) { + if (gpio_chip->start > new_gpio_chip->end) { + list_add_tail(&new_gpio_chip->list, &gpio_chip->list); + goto added; + } + if (gpio_chip->end >= new_gpio_chip->start) { + printk(KERN_ERR "register_gpio_source %u-%u overlaps with %u-%u\n", + new_gpio_chip->start, new_gpio_chip->end, + gpio_chip->start, gpio_chip->end); + err = -EBUSY; + goto failed; + } + } + list_add_tail(&new_gpio_chip->list, &gpio_chip_list); +added: + for (i = chip_array_start_index; i <= chip_array_end_index; i++) { + if (gpio_chip_array[i] == NULL || gpio_chip_array[i]->start > new_gpio_chip->start) + gpio_chip_array[i] = new_gpio_chip; + } +failed: + spin_unlock_irqrestore(&gpio_chips_lock, irq_flags); + if (err) + kfree(new_gpio_chip->state); + return err; +} + +static struct gpio_chip *get_gpio_chip_locked(unsigned int gpio) +{ + unsigned long i; + struct gpio_chip *chip; + + i = GPIO_NUM_TO_CHIP_INDEX(gpio); + if (i >= gpio_chip_array_size) + return NULL; + chip = gpio_chip_array[i]; + if (chip == NULL) + return NULL; + list_for_each_entry_from(chip, &gpio_chip_list, list) { + if (gpio < chip->start) + return NULL; + if (gpio <= chip->end) + return chip; + } + return NULL; +} + +static int request_gpio(unsigned int gpio, unsigned long flags) +{ + int err = 0; + struct gpio_chip *chip; + unsigned long irq_flags; + unsigned long chip_index; + + spin_lock_irqsave(&gpio_chips_lock, irq_flags); + chip = get_gpio_chip_locked(gpio); + if (chip == NULL) { + err = -EINVAL; + goto err; + } + chip_index = gpio - chip->start; + if (chip->state[chip_index].refcount == 0) { + chip->configure(chip, gpio, flags); + chip->state[chip_index].flags = flags; + chip->state[chip_index].refcount++; + } else if ((flags & IRQF_SHARED) && (chip->state[chip_index].flags & IRQF_SHARED)) + chip->state[chip_index].refcount++; + else + err = -EBUSY; +err: + spin_unlock_irqrestore(&gpio_chips_lock, irq_flags); + return err; +} + +int gpio_request(unsigned gpio, const char *label) +{ + return request_gpio(gpio, 0); +} +EXPORT_SYMBOL(gpio_request); + +void gpio_free(unsigned gpio) +{ + struct gpio_chip *chip; + unsigned long irq_flags; + unsigned long chip_index; + + spin_lock_irqsave(&gpio_chips_lock, irq_flags); + chip = get_gpio_chip_locked(gpio); + if (chip) { + chip_index = gpio - chip->start; + chip->state[chip_index].refcount--; + } + spin_unlock_irqrestore(&gpio_chips_lock, irq_flags); +} +EXPORT_SYMBOL(gpio_free); + +static int gpio_get_irq_num(unsigned int gpio, unsigned int *irqp, unsigned long *irqnumflagsp) +{ + int ret = -ENOTSUPP; + struct gpio_chip *chip; + unsigned long irq_flags; + + spin_lock_irqsave(&gpio_chips_lock, irq_flags); + chip = get_gpio_chip_locked(gpio); + if (chip && chip->get_irq_num) + ret = chip->get_irq_num(chip, gpio, irqp, irqnumflagsp); + spin_unlock_irqrestore(&gpio_chips_lock, irq_flags); + return ret; +} + +int gpio_to_irq(unsigned gpio) +{ + int ret, irq; + ret = gpio_get_irq_num(gpio, &irq, NULL); + if (ret) + return ret; + return irq; +} +EXPORT_SYMBOL(gpio_to_irq); + +int gpio_configure(unsigned int gpio, unsigned long flags) +{ + int ret = -ENOTSUPP; + struct gpio_chip *chip; + unsigned long irq_flags; + + spin_lock_irqsave(&gpio_chips_lock, irq_flags); + chip = get_gpio_chip_locked(gpio); + if (chip) + ret = chip->configure(chip, gpio, flags); + spin_unlock_irqrestore(&gpio_chips_lock, irq_flags); + return ret; +} +EXPORT_SYMBOL(gpio_configure); + +int gpio_direction_input(unsigned gpio) +{ + return gpio_configure(gpio, GPIOF_INPUT); +} +EXPORT_SYMBOL(gpio_direction_input); + +int gpio_direction_output(unsigned gpio, int value) +{ + gpio_set_value(gpio, value); + return gpio_configure(gpio, GPIOF_DRIVE_OUTPUT); +} +EXPORT_SYMBOL(gpio_direction_output); + +int gpio_get_value(unsigned gpio) +{ + int ret = -ENOTSUPP; + struct gpio_chip *chip; + unsigned long irq_flags; + + spin_lock_irqsave(&gpio_chips_lock, irq_flags); + chip = get_gpio_chip_locked(gpio); + if (chip && chip->read) + ret = chip->read(chip, gpio); + spin_unlock_irqrestore(&gpio_chips_lock, irq_flags); + return ret; +} +EXPORT_SYMBOL(gpio_get_value); + +void gpio_set_value(unsigned gpio, int on) +{ + int ret = -ENOTSUPP; + struct gpio_chip *chip; + unsigned long irq_flags; + + spin_lock_irqsave(&gpio_chips_lock, irq_flags); + chip = get_gpio_chip_locked(gpio); + if (chip && chip->write) + ret = chip->write(chip, gpio, on); + spin_unlock_irqrestore(&gpio_chips_lock, irq_flags); +} +EXPORT_SYMBOL(gpio_set_value); + +int gpio_read_detect_status(unsigned int gpio) +{ + int ret = -ENOTSUPP; + struct gpio_chip *chip; + unsigned long irq_flags; + + spin_lock_irqsave(&gpio_chips_lock, irq_flags); + chip = get_gpio_chip_locked(gpio); + if (chip && chip->read_detect_status) + ret = chip->read_detect_status(chip, gpio); + spin_unlock_irqrestore(&gpio_chips_lock, irq_flags); + return ret; +} +EXPORT_SYMBOL(gpio_read_detect_status); + +int gpio_clear_detect_status(unsigned int gpio) +{ + int ret = -ENOTSUPP; + struct gpio_chip *chip; + unsigned long irq_flags; + + spin_lock_irqsave(&gpio_chips_lock, irq_flags); + chip = get_gpio_chip_locked(gpio); + if (chip && chip->clear_detect_status) + ret = chip->clear_detect_status(chip, gpio); + spin_unlock_irqrestore(&gpio_chips_lock, irq_flags); + return ret; +} +EXPORT_SYMBOL(gpio_clear_detect_status); diff --git a/trunk/drivers/staging/dream/gpio_axis.c b/trunk/drivers/staging/dream/gpio_axis.c new file mode 100644 index 000000000000..eb54724b1d3a --- /dev/null +++ b/trunk/drivers/staging/dream/gpio_axis.c @@ -0,0 +1,181 @@ +/* drivers/input/misc/gpio_axis.c + * + * Copyright (C) 2007 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include + +struct gpio_axis_state { + struct input_dev *input_dev; + struct gpio_event_axis_info *info; + uint32_t pos; +}; + +uint16_t gpio_axis_4bit_gray_map_table[] = { + [0x0] = 0x0, [0x1] = 0x1, /* 0000 0001 */ + [0x3] = 0x2, [0x2] = 0x3, /* 0011 0010 */ + [0x6] = 0x4, [0x7] = 0x5, /* 0110 0111 */ + [0x5] = 0x6, [0x4] = 0x7, /* 0101 0100 */ + [0xc] = 0x8, [0xd] = 0x9, /* 1100 1101 */ + [0xf] = 0xa, [0xe] = 0xb, /* 1111 1110 */ + [0xa] = 0xc, [0xb] = 0xd, /* 1010 1011 */ + [0x9] = 0xe, [0x8] = 0xf, /* 1001 1000 */ +}; +uint16_t gpio_axis_4bit_gray_map(struct gpio_event_axis_info *info, uint16_t in) +{ + return gpio_axis_4bit_gray_map_table[in]; +} + +uint16_t gpio_axis_5bit_singletrack_map_table[] = { + [0x10] = 0x00, [0x14] = 0x01, [0x1c] = 0x02, /* 10000 10100 11100 */ + [0x1e] = 0x03, [0x1a] = 0x04, [0x18] = 0x05, /* 11110 11010 11000 */ + [0x08] = 0x06, [0x0a] = 0x07, [0x0e] = 0x08, /* 01000 01010 01110 */ + [0x0f] = 0x09, [0x0d] = 0x0a, [0x0c] = 0x0b, /* 01111 01101 01100 */ + [0x04] = 0x0c, [0x05] = 0x0d, [0x07] = 0x0e, /* 00100 00101 00111 */ + [0x17] = 0x0f, [0x16] = 0x10, [0x06] = 0x11, /* 10111 10110 00110 */ + [0x02] = 0x12, [0x12] = 0x13, [0x13] = 0x14, /* 00010 10010 10011 */ + [0x1b] = 0x15, [0x0b] = 0x16, [0x03] = 0x17, /* 11011 01011 00011 */ + [0x01] = 0x18, [0x09] = 0x19, [0x19] = 0x1a, /* 00001 01001 11001 */ + [0x1d] = 0x1b, [0x15] = 0x1c, [0x11] = 0x1d, /* 11101 10101 10001 */ +}; +uint16_t gpio_axis_5bit_singletrack_map( + struct gpio_event_axis_info *info, uint16_t in) +{ + return gpio_axis_5bit_singletrack_map_table[in]; +} + +static void gpio_event_update_axis(struct gpio_axis_state *as, int report) +{ + struct gpio_event_axis_info *ai = as->info; + int i; + int change; + uint16_t state = 0; + uint16_t pos; + uint16_t old_pos = as->pos; + for (i = ai->count - 1; i >= 0; i--) + state = (state << 1) | gpio_get_value(ai->gpio[i]); + pos = ai->map(ai, state); + if (ai->flags & GPIOEAF_PRINT_RAW) + pr_info("axis %d-%d raw %x, pos %d -> %d\n", + ai->type, ai->code, state, old_pos, pos); + if (report && pos != old_pos) { + if (ai->type == EV_REL) { + change = (ai->decoded_size + pos - old_pos) % + ai->decoded_size; + if (change > ai->decoded_size / 2) + change -= ai->decoded_size; + if (change == ai->decoded_size / 2) { + if (ai->flags & GPIOEAF_PRINT_EVENT) + pr_info("axis %d-%d unknown direction, " + "pos %d -> %d\n", ai->type, + ai->code, old_pos, pos); + change = 0; /* no closest direction */ + } + if (ai->flags & GPIOEAF_PRINT_EVENT) + pr_info("axis %d-%d change %d\n", + ai->type, ai->code, change); + input_report_rel(as->input_dev, ai->code, change); + } else { + if (ai->flags & GPIOEAF_PRINT_EVENT) + pr_info("axis %d-%d now %d\n", + ai->type, ai->code, pos); + input_event(as->input_dev, ai->type, ai->code, pos); + } + input_sync(as->input_dev); + } + as->pos = pos; +} + +static irqreturn_t gpio_axis_irq_handler(int irq, void *dev_id) +{ + struct gpio_axis_state *as = dev_id; + gpio_event_update_axis(as, 1); + return IRQ_HANDLED; +} + +int gpio_event_axis_func(struct input_dev *input_dev, + struct gpio_event_info *info, void **data, int func) +{ + int ret; + int i; + int irq; + struct gpio_event_axis_info *ai; + struct gpio_axis_state *as; + + ai = container_of(info, struct gpio_event_axis_info, info); + if (func == GPIO_EVENT_FUNC_SUSPEND) { + for (i = 0; i < ai->count; i++) + disable_irq(gpio_to_irq(ai->gpio[i])); + return 0; + } + if (func == GPIO_EVENT_FUNC_RESUME) { + for (i = 0; i < ai->count; i++) + enable_irq(gpio_to_irq(ai->gpio[i])); + return 0; + } + + if (func == GPIO_EVENT_FUNC_INIT) { + *data = as = kmalloc(sizeof(*as), GFP_KERNEL); + if (as == NULL) { + ret = -ENOMEM; + goto err_alloc_axis_state_failed; + } + as->input_dev = input_dev; + as->info = ai; + + input_set_capability(input_dev, ai->type, ai->code); + if (ai->type == EV_ABS) { + input_set_abs_params(input_dev, ai->code, 0, + ai->decoded_size - 1, 0, 0); + } + for (i = 0; i < ai->count; i++) { + ret = gpio_request(ai->gpio[i], "gpio_event_axis"); + if (ret < 0) + goto err_request_gpio_failed; + ret = gpio_direction_input(ai->gpio[i]); + if (ret < 0) + goto err_gpio_direction_input_failed; + ret = irq = gpio_to_irq(ai->gpio[i]); + if (ret < 0) + goto err_get_irq_num_failed; + ret = request_irq(irq, gpio_axis_irq_handler, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING, + "gpio_event_axis", as); + if (ret < 0) + goto err_request_irq_failed; + } + gpio_event_update_axis(as, 0); + return 0; + } + + ret = 0; + as = *data; + for (i = ai->count - 1; i >= 0; i--) { + free_irq(gpio_to_irq(ai->gpio[i]), as); +err_request_irq_failed: +err_get_irq_num_failed: +err_gpio_direction_input_failed: + gpio_free(ai->gpio[i]); +err_request_gpio_failed: + ; + } + kfree(as); + *data = NULL; +err_alloc_axis_state_failed: + return ret; +} diff --git a/trunk/drivers/staging/dream/gpio_event.c b/trunk/drivers/staging/dream/gpio_event.c new file mode 100644 index 000000000000..97a511d11f49 --- /dev/null +++ b/trunk/drivers/staging/dream/gpio_event.c @@ -0,0 +1,224 @@ +/* drivers/input/misc/gpio_event.c + * + * Copyright (C) 2007 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + + +#include +#include +#include +#include +#include +#include + +struct gpio_event { + struct input_dev *input_dev; + const struct gpio_event_platform_data *info; + void *state[0]; +}; + +static int gpio_input_event( + struct input_dev *dev, unsigned int type, unsigned int code, int value) +{ + int i; + int ret = 0; + int tmp_ret; + struct gpio_event_info **ii; + struct gpio_event *ip = input_get_drvdata(dev); + + for (i = 0, ii = ip->info->info; i < ip->info->info_count; i++, ii++) { + if ((*ii)->event) { + tmp_ret = (*ii)->event(ip->input_dev, *ii, + &ip->state[i], type, code, value); + if (tmp_ret) + ret = tmp_ret; + } + } + return ret; +} + +static int gpio_event_call_all_func(struct gpio_event *ip, int func) +{ + int i; + int ret; + struct gpio_event_info **ii; + + if (func == GPIO_EVENT_FUNC_INIT || func == GPIO_EVENT_FUNC_RESUME) { + ii = ip->info->info; + for (i = 0; i < ip->info->info_count; i++, ii++) { + if ((*ii)->func == NULL) { + ret = -ENODEV; + pr_err("gpio_event_probe: Incomplete pdata, " + "no function\n"); + goto err_no_func; + } + ret = (*ii)->func(ip->input_dev, *ii, &ip->state[i], + func); + if (ret) { + pr_err("gpio_event_probe: function failed\n"); + goto err_func_failed; + } + } + return 0; + } + + ret = 0; + i = ip->info->info_count; + ii = ip->info->info + i; + while (i > 0) { + i--; + ii--; + (*ii)->func(ip->input_dev, *ii, &ip->state[i], func & ~1); +err_func_failed: +err_no_func: + ; + } + return ret; +} + +#ifdef CONFIG_HAS_EARLYSUSPEND +void gpio_event_suspend(struct early_suspend *h) +{ + struct gpio_event *ip; + ip = container_of(h, struct gpio_event, early_suspend); + gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_SUSPEND); + ip->info->power(ip->info, 0); +} + +void gpio_event_resume(struct early_suspend *h) +{ + struct gpio_event *ip; + ip = container_of(h, struct gpio_event, early_suspend); + ip->info->power(ip->info, 1); + gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_RESUME); +} +#endif + +static int __init gpio_event_probe(struct platform_device *pdev) +{ + int err; + struct gpio_event *ip; + struct input_dev *input_dev; + struct gpio_event_platform_data *event_info; + + event_info = pdev->dev.platform_data; + if (event_info == NULL) { + pr_err("gpio_event_probe: No pdata\n"); + return -ENODEV; + } + if (event_info->name == NULL || + event_info->info == NULL || + event_info->info_count == 0) { + pr_err("gpio_event_probe: Incomplete pdata\n"); + return -ENODEV; + } + ip = kzalloc(sizeof(*ip) + + sizeof(ip->state[0]) * event_info->info_count, GFP_KERNEL); + if (ip == NULL) { + err = -ENOMEM; + pr_err("gpio_event_probe: Failed to allocate private data\n"); + goto err_kp_alloc_failed; + } + platform_set_drvdata(pdev, ip); + + input_dev = input_allocate_device(); + if (input_dev == NULL) { + err = -ENOMEM; + pr_err("gpio_event_probe: Failed to allocate input device\n"); + goto err_input_dev_alloc_failed; + } + input_set_drvdata(input_dev, ip); + ip->input_dev = input_dev; + ip->info = event_info; + if (event_info->power) { +#ifdef CONFIG_HAS_EARLYSUSPEND + ip->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + ip->early_suspend.suspend = gpio_event_suspend; + ip->early_suspend.resume = gpio_event_resume; + register_early_suspend(&ip->early_suspend); +#endif + ip->info->power(ip->info, 1); + } + + input_dev->name = ip->info->name; + input_dev->event = gpio_input_event; + + err = gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_INIT); + if (err) + goto err_call_all_func_failed; + + err = input_register_device(input_dev); + if (err) { + pr_err("gpio_event_probe: Unable to register %s input device\n", + input_dev->name); + goto err_input_register_device_failed; + } + + return 0; + +err_input_register_device_failed: + gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT); +err_call_all_func_failed: + if (event_info->power) { +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&ip->early_suspend); +#endif + ip->info->power(ip->info, 0); + } + input_free_device(input_dev); +err_input_dev_alloc_failed: + kfree(ip); +err_kp_alloc_failed: + return err; +} + +static int gpio_event_remove(struct platform_device *pdev) +{ + struct gpio_event *ip = platform_get_drvdata(pdev); + + gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT); + if (ip->info->power) { +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&ip->early_suspend); +#endif + ip->info->power(ip->info, 0); + } + input_unregister_device(ip->input_dev); + kfree(ip); + return 0; +} + +static struct platform_driver gpio_event_driver = { + .probe = gpio_event_probe, + .remove = gpio_event_remove, + .driver = { + .name = GPIO_EVENT_DEV_NAME, + }, +}; + +static int __devinit gpio_event_init(void) +{ + return platform_driver_register(&gpio_event_driver); +} + +static void __exit gpio_event_exit(void) +{ + platform_driver_unregister(&gpio_event_driver); +} + +module_init(gpio_event_init); +module_exit(gpio_event_exit); + +MODULE_DESCRIPTION("GPIO Event Driver"); +MODULE_LICENSE("GPL"); + diff --git a/trunk/drivers/staging/dream/gpio_input.c b/trunk/drivers/staging/dream/gpio_input.c new file mode 100644 index 000000000000..ca29e5eb070a --- /dev/null +++ b/trunk/drivers/staging/dream/gpio_input.c @@ -0,0 +1,337 @@ +/* drivers/input/misc/gpio_input.c + * + * Copyright (C) 2007 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +enum { + DEBOUNCE_UNSTABLE = BIT(0), /* Got irq, while debouncing */ + DEBOUNCE_PRESSED = BIT(1), + DEBOUNCE_NOTPRESSED = BIT(2), + DEBOUNCE_WAIT_IRQ = BIT(3), /* Stable irq state */ + DEBOUNCE_POLL = BIT(4), /* Stable polling state */ + + DEBOUNCE_UNKNOWN = + DEBOUNCE_PRESSED | DEBOUNCE_NOTPRESSED, +}; + +struct gpio_key_state { + struct gpio_input_state *ds; + uint8_t debounce; +}; + +struct gpio_input_state { + struct input_dev *input_dev; + const struct gpio_event_input_info *info; + struct hrtimer timer; + int use_irq; + int debounce_count; + spinlock_t irq_lock; + struct gpio_key_state key_state[0]; +}; + +static enum hrtimer_restart gpio_event_input_timer_func(struct hrtimer *timer) +{ + int i; + int pressed; + struct gpio_input_state *ds = + container_of(timer, struct gpio_input_state, timer); + unsigned gpio_flags = ds->info->flags; + unsigned npolarity; + int nkeys = ds->info->keymap_size; + const struct gpio_event_direct_entry *key_entry; + struct gpio_key_state *key_state; + unsigned long irqflags; + uint8_t debounce; + +#if 0 + key_entry = kp->keys_info->keymap; + key_state = kp->key_state; + for (i = 0; i < nkeys; i++, key_entry++, key_state++) + pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio, + gpio_read_detect_status(key_entry->gpio)); +#endif + key_entry = ds->info->keymap; + key_state = ds->key_state; + spin_lock_irqsave(&ds->irq_lock, irqflags); + for (i = 0; i < nkeys; i++, key_entry++, key_state++) { + debounce = key_state->debounce; + if (debounce & DEBOUNCE_WAIT_IRQ) + continue; + if (key_state->debounce & DEBOUNCE_UNSTABLE) { + debounce = key_state->debounce = DEBOUNCE_UNKNOWN; + enable_irq(gpio_to_irq(key_entry->gpio)); + pr_info("gpio_keys_scan_keys: key %x-%x, %d " + "(%d) continue debounce\n", + ds->info->type, key_entry->code, + i, key_entry->gpio); + } + npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH); + pressed = gpio_get_value(key_entry->gpio) ^ npolarity; + if (debounce & DEBOUNCE_POLL) { + if (pressed == !(debounce & DEBOUNCE_PRESSED)) { + ds->debounce_count++; + key_state->debounce = DEBOUNCE_UNKNOWN; + if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) + pr_info("gpio_keys_scan_keys: key %x-" + "%x, %d (%d) start debounce\n", + ds->info->type, key_entry->code, + i, key_entry->gpio); + } + continue; + } + if (pressed && (debounce & DEBOUNCE_NOTPRESSED)) { + if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) + pr_info("gpio_keys_scan_keys: key %x-%x, %d " + "(%d) debounce pressed 1\n", + ds->info->type, key_entry->code, + i, key_entry->gpio); + key_state->debounce = DEBOUNCE_PRESSED; + continue; + } + if (!pressed && (debounce & DEBOUNCE_PRESSED)) { + if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) + pr_info("gpio_keys_scan_keys: key %x-%x, %d " + "(%d) debounce pressed 0\n", + ds->info->type, key_entry->code, + i, key_entry->gpio); + key_state->debounce = DEBOUNCE_NOTPRESSED; + continue; + } + /* key is stable */ + ds->debounce_count--; + if (ds->use_irq) + key_state->debounce |= DEBOUNCE_WAIT_IRQ; + else + key_state->debounce |= DEBOUNCE_POLL; + if (gpio_flags & GPIOEDF_PRINT_KEYS) + pr_info("gpio_keys_scan_keys: key %x-%x, %d (%d) " + "changed to %d\n", ds->info->type, + key_entry->code, i, key_entry->gpio, pressed); + input_event(ds->input_dev, ds->info->type, + key_entry->code, pressed); + } + +#if 0 + key_entry = kp->keys_info->keymap; + key_state = kp->key_state; + for (i = 0; i < nkeys; i++, key_entry++, key_state++) { + pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio, + gpio_read_detect_status(key_entry->gpio)); + } +#endif + + if (ds->debounce_count) + hrtimer_start(timer, ds->info->debounce_time, HRTIMER_MODE_REL); + else if (!ds->use_irq) + hrtimer_start(timer, ds->info->poll_time, HRTIMER_MODE_REL); + + spin_unlock_irqrestore(&ds->irq_lock, irqflags); + + return HRTIMER_NORESTART; +} + +static irqreturn_t gpio_event_input_irq_handler(int irq, void *dev_id) +{ + struct gpio_key_state *ks = dev_id; + struct gpio_input_state *ds = ks->ds; + int keymap_index = ks - ds->key_state; + const struct gpio_event_direct_entry *key_entry; + unsigned long irqflags; + int pressed; + + if (!ds->use_irq) + return IRQ_HANDLED; + + key_entry = &ds->info->keymap[keymap_index]; + + if (ds->info->debounce_time.tv64) { + spin_lock_irqsave(&ds->irq_lock, irqflags); + if (ks->debounce & DEBOUNCE_WAIT_IRQ) { + ks->debounce = DEBOUNCE_UNKNOWN; + if (ds->debounce_count++ == 0) { + hrtimer_start( + &ds->timer, ds->info->debounce_time, + HRTIMER_MODE_REL); + } + if (ds->info->flags & GPIOEDF_PRINT_KEY_DEBOUNCE) + pr_info("gpio_event_input_irq_handler: " + "key %x-%x, %d (%d) start debounce\n", + ds->info->type, key_entry->code, + keymap_index, key_entry->gpio); + } else { + disable_irq(irq); + ks->debounce = DEBOUNCE_UNSTABLE; + } + spin_unlock_irqrestore(&ds->irq_lock, irqflags); + } else { + pressed = gpio_get_value(key_entry->gpio) ^ + !(ds->info->flags & GPIOEDF_ACTIVE_HIGH); + if (ds->info->flags & GPIOEDF_PRINT_KEYS) + pr_info("gpio_event_input_irq_handler: key %x-%x, %d " + "(%d) changed to %d\n", + ds->info->type, key_entry->code, keymap_index, + key_entry->gpio, pressed); + input_event(ds->input_dev, ds->info->type, + key_entry->code, pressed); + } + return IRQ_HANDLED; +} + +static int gpio_event_input_request_irqs(struct gpio_input_state *ds) +{ + int i; + int err; + unsigned int irq; + unsigned long req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; + + for (i = 0; i < ds->info->keymap_size; i++) { + err = irq = gpio_to_irq(ds->info->keymap[i].gpio); + if (err < 0) + goto err_gpio_get_irq_num_failed; + err = request_irq(irq, gpio_event_input_irq_handler, + req_flags, "gpio_keys", &ds->key_state[i]); + if (err) { + pr_err("gpio_event_input_request_irqs: request_irq " + "failed for input %d, irq %d\n", + ds->info->keymap[i].gpio, irq); + goto err_request_irq_failed; + } + enable_irq_wake(irq); + } + return 0; + + for (i = ds->info->keymap_size - 1; i >= 0; i--) { + free_irq(gpio_to_irq(ds->info->keymap[i].gpio), + &ds->key_state[i]); +err_request_irq_failed: +err_gpio_get_irq_num_failed: + ; + } + return err; +} + +int gpio_event_input_func(struct input_dev *input_dev, + struct gpio_event_info *info, void **data, int func) +{ + int ret; + int i; + unsigned long irqflags; + struct gpio_event_input_info *di; + struct gpio_input_state *ds = *data; + + di = container_of(info, struct gpio_event_input_info, info); + + if (func == GPIO_EVENT_FUNC_SUSPEND) { + spin_lock_irqsave(&ds->irq_lock, irqflags); + if (ds->use_irq) + for (i = 0; i < di->keymap_size; i++) + disable_irq(gpio_to_irq(di->keymap[i].gpio)); + spin_unlock_irqrestore(&ds->irq_lock, irqflags); + hrtimer_cancel(&ds->timer); + return 0; + } + if (func == GPIO_EVENT_FUNC_RESUME) { + spin_lock_irqsave(&ds->irq_lock, irqflags); + if (ds->use_irq) + for (i = 0; i < di->keymap_size; i++) + enable_irq(gpio_to_irq(di->keymap[i].gpio)); + hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL); + spin_unlock_irqrestore(&ds->irq_lock, irqflags); + return 0; + } + + if (func == GPIO_EVENT_FUNC_INIT) { + if (ktime_to_ns(di->poll_time) <= 0) + di->poll_time = ktime_set(0, 20 * NSEC_PER_MSEC); + + *data = ds = kzalloc(sizeof(*ds) + sizeof(ds->key_state[0]) * + di->keymap_size, GFP_KERNEL); + if (ds == NULL) { + ret = -ENOMEM; + pr_err("gpio_event_input_func: " + "Failed to allocate private data\n"); + goto err_ds_alloc_failed; + } + ds->debounce_count = di->keymap_size; + ds->input_dev = input_dev; + ds->info = di; + spin_lock_init(&ds->irq_lock); + + for (i = 0; i < di->keymap_size; i++) { + input_set_capability(input_dev, di->type, + di->keymap[i].code); + ds->key_state[i].ds = ds; + ds->key_state[i].debounce = DEBOUNCE_UNKNOWN; + } + + for (i = 0; i < di->keymap_size; i++) { + ret = gpio_request(di->keymap[i].gpio, "gpio_kp_in"); + if (ret) { + pr_err("gpio_event_input_func: gpio_request " + "failed for %d\n", di->keymap[i].gpio); + goto err_gpio_request_failed; + } + ret = gpio_direction_input(di->keymap[i].gpio); + if (ret) { + pr_err("gpio_event_input_func: " + "gpio_direction_input failed for %d\n", + di->keymap[i].gpio); + goto err_gpio_configure_failed; + } + } + + ret = gpio_event_input_request_irqs(ds); + + spin_lock_irqsave(&ds->irq_lock, irqflags); + ds->use_irq = ret == 0; + + pr_info("GPIO Input Driver: Start gpio inputs for %s in %s " + "mode\n", + input_dev->name, ret == 0 ? "interrupt" : "polling"); + + hrtimer_init(&ds->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + ds->timer.function = gpio_event_input_timer_func; + hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL); + spin_unlock_irqrestore(&ds->irq_lock, irqflags); + return 0; + } + + ret = 0; + spin_lock_irqsave(&ds->irq_lock, irqflags); + hrtimer_cancel(&ds->timer); + if (ds->use_irq) { + for (i = di->keymap_size - 1; i >= 0; i--) { + free_irq(gpio_to_irq(di->keymap[i].gpio), + &ds->key_state[i]); + } + } + spin_unlock_irqrestore(&ds->irq_lock, irqflags); + + for (i = di->keymap_size - 1; i >= 0; i--) { +err_gpio_configure_failed: + gpio_free(di->keymap[i].gpio); +err_gpio_request_failed: + ; + } + kfree(ds); +err_ds_alloc_failed: + return ret; +} diff --git a/trunk/drivers/staging/dream/gpio_matrix.c b/trunk/drivers/staging/dream/gpio_matrix.c new file mode 100644 index 000000000000..b377ee1f5a5f --- /dev/null +++ b/trunk/drivers/staging/dream/gpio_matrix.c @@ -0,0 +1,399 @@ +/* drivers/input/misc/gpio_matrix.c + * + * Copyright (C) 2007 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include + +struct gpio_kp { + struct input_dev *input_dev; + struct gpio_event_matrix_info *keypad_info; + struct hrtimer timer; + int current_output; + unsigned int use_irq:1; + unsigned int key_state_changed:1; + unsigned int last_key_state_changed:1; + unsigned int some_keys_pressed:2; + unsigned long keys_pressed[0]; +}; + +static void clear_phantom_key(struct gpio_kp *kp, int out, int in) +{ + struct gpio_event_matrix_info *mi = kp->keypad_info; + int key_index = out * mi->ninputs + in; + unsigned short keycode = mi->keymap[key_index];; + + if (!test_bit(keycode, kp->input_dev->key)) { + if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS) + pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) " + "cleared\n", keycode, out, in, + mi->output_gpios[out], mi->input_gpios[in]); + __clear_bit(key_index, kp->keys_pressed); + } else { + if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS) + pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) " + "not cleared\n", keycode, out, in, + mi->output_gpios[out], mi->input_gpios[in]); + } +} + +static int restore_keys_for_input(struct gpio_kp *kp, int out, int in) +{ + int rv = 0; + int key_index; + + key_index = out * kp->keypad_info->ninputs + in; + while (out < kp->keypad_info->noutputs) { + if (test_bit(key_index, kp->keys_pressed)) { + rv = 1; + clear_phantom_key(kp, out, in); + } + key_index += kp->keypad_info->ninputs; + out++; + } + return rv; +} + +static void remove_phantom_keys(struct gpio_kp *kp) +{ + int out, in, inp; + int key_index; + + if (kp->some_keys_pressed < 3) + return; + + for (out = 0; out < kp->keypad_info->noutputs; out++) { + inp = -1; + key_index = out * kp->keypad_info->ninputs; + for (in = 0; in < kp->keypad_info->ninputs; in++, key_index++) { + if (test_bit(key_index, kp->keys_pressed)) { + if (inp == -1) { + inp = in; + continue; + } + if (inp >= 0) { + if (!restore_keys_for_input(kp, out + 1, + inp)) + break; + clear_phantom_key(kp, out, inp); + inp = -2; + } + restore_keys_for_input(kp, out, in); + } + } + } +} + +static void report_key(struct gpio_kp *kp, int key_index, int out, int in) +{ + struct gpio_event_matrix_info *mi = kp->keypad_info; + int pressed = test_bit(key_index, kp->keys_pressed); + unsigned short keycode = mi->keymap[key_index]; + if (pressed != test_bit(keycode, kp->input_dev->key)) { + if (keycode == KEY_RESERVED) { + if (mi->flags & GPIOKPF_PRINT_UNMAPPED_KEYS) + pr_info("gpiomatrix: unmapped key, %d-%d " + "(%d-%d) changed to %d\n", + out, in, mi->output_gpios[out], + mi->input_gpios[in], pressed); + } else { + if (mi->flags & GPIOKPF_PRINT_MAPPED_KEYS) + pr_info("gpiomatrix: key %x, %d-%d (%d-%d) " + "changed to %d\n", keycode, + out, in, mi->output_gpios[out], + mi->input_gpios[in], pressed); + input_report_key(kp->input_dev, keycode, pressed); + } + } +} + +static enum hrtimer_restart gpio_keypad_timer_func(struct hrtimer *timer) +{ + int out, in; + int key_index; + int gpio; + struct gpio_kp *kp = container_of(timer, struct gpio_kp, timer); + struct gpio_event_matrix_info *mi = kp->keypad_info; + unsigned gpio_keypad_flags = mi->flags; + unsigned polarity = !!(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH); + + out = kp->current_output; + if (out == mi->noutputs) { + out = 0; + kp->last_key_state_changed = kp->key_state_changed; + kp->key_state_changed = 0; + kp->some_keys_pressed = 0; + } else { + key_index = out * mi->ninputs; + for (in = 0; in < mi->ninputs; in++, key_index++) { + gpio = mi->input_gpios[in]; + if (gpio_get_value(gpio) ^ !polarity) { + if (kp->some_keys_pressed < 3) + kp->some_keys_pressed++; + kp->key_state_changed |= !__test_and_set_bit( + key_index, kp->keys_pressed); + } else + kp->key_state_changed |= __test_and_clear_bit( + key_index, kp->keys_pressed); + } + gpio = mi->output_gpios[out]; + if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) + gpio_set_value(gpio, !polarity); + else + gpio_direction_input(gpio); + out++; + } + kp->current_output = out; + if (out < mi->noutputs) { + gpio = mi->output_gpios[out]; + if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) + gpio_set_value(gpio, polarity); + else + gpio_direction_output(gpio, polarity); + hrtimer_start(timer, mi->settle_time, HRTIMER_MODE_REL); + return HRTIMER_NORESTART; + } + if (gpio_keypad_flags & GPIOKPF_DEBOUNCE) { + if (kp->key_state_changed) { + hrtimer_start(&kp->timer, mi->debounce_delay, + HRTIMER_MODE_REL); + return HRTIMER_NORESTART; + } + kp->key_state_changed = kp->last_key_state_changed; + } + if (kp->key_state_changed) { + if (gpio_keypad_flags & GPIOKPF_REMOVE_SOME_PHANTOM_KEYS) + remove_phantom_keys(kp); + key_index = 0; + for (out = 0; out < mi->noutputs; out++) + for (in = 0; in < mi->ninputs; in++, key_index++) + report_key(kp, key_index, out, in); + } + if (!kp->use_irq || kp->some_keys_pressed) { + hrtimer_start(timer, mi->poll_time, HRTIMER_MODE_REL); + return HRTIMER_NORESTART; + } + + /* No keys are pressed, reenable interrupt */ + for (out = 0; out < mi->noutputs; out++) { + if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) + gpio_set_value(mi->output_gpios[out], polarity); + else + gpio_direction_output(mi->output_gpios[out], polarity); + } + for (in = 0; in < mi->ninputs; in++) + enable_irq(gpio_to_irq(mi->input_gpios[in])); + return HRTIMER_NORESTART; +} + +static irqreturn_t gpio_keypad_irq_handler(int irq_in, void *dev_id) +{ + int i; + struct gpio_kp *kp = dev_id; + struct gpio_event_matrix_info *mi = kp->keypad_info; + unsigned gpio_keypad_flags = mi->flags; + + if (!kp->use_irq) /* ignore interrupt while registering the handler */ + return IRQ_HANDLED; + + for (i = 0; i < mi->ninputs; i++) + disable_irq(gpio_to_irq(mi->input_gpios[i])); + for (i = 0; i < mi->noutputs; i++) { + if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) + gpio_set_value(mi->output_gpios[i], + !(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH)); + else + gpio_direction_input(mi->output_gpios[i]); + } + hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL); + return IRQ_HANDLED; +} + +static int gpio_keypad_request_irqs(struct gpio_kp *kp) +{ + int i; + int err; + unsigned int irq; + unsigned long request_flags; + struct gpio_event_matrix_info *mi = kp->keypad_info; + + switch (mi->flags & (GPIOKPF_ACTIVE_HIGH|GPIOKPF_LEVEL_TRIGGERED_IRQ)) { + default: + request_flags = IRQF_TRIGGER_FALLING; + break; + case GPIOKPF_ACTIVE_HIGH: + request_flags = IRQF_TRIGGER_RISING; + break; + case GPIOKPF_LEVEL_TRIGGERED_IRQ: + request_flags = IRQF_TRIGGER_LOW; + break; + case GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH: + request_flags = IRQF_TRIGGER_HIGH; + break; + } + + for (i = 0; i < mi->ninputs; i++) { + err = irq = gpio_to_irq(mi->input_gpios[i]); + if (err < 0) + goto err_gpio_get_irq_num_failed; + err = request_irq(irq, gpio_keypad_irq_handler, request_flags, + "gpio_kp", kp); + if (err) { + pr_err("gpiomatrix: request_irq failed for input %d, " + "irq %d\n", mi->input_gpios[i], irq); + goto err_request_irq_failed; + } + err = set_irq_wake(irq, 1); + if (err) { + pr_err("gpiomatrix: set_irq_wake failed for input %d, " + "irq %d\n", mi->input_gpios[i], irq); + } + disable_irq(irq); + } + return 0; + + for (i = mi->noutputs - 1; i >= 0; i--) { + free_irq(gpio_to_irq(mi->input_gpios[i]), kp); +err_request_irq_failed: +err_gpio_get_irq_num_failed: + ; + } + return err; +} + +int gpio_event_matrix_func(struct input_dev *input_dev, + struct gpio_event_info *info, void **data, int func) +{ + int i; + int err; + int key_count; + struct gpio_kp *kp; + struct gpio_event_matrix_info *mi; + + mi = container_of(info, struct gpio_event_matrix_info, info); + if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) { + /* TODO: disable scanning */ + return 0; + } + + if (func == GPIO_EVENT_FUNC_INIT) { + if (mi->keymap == NULL || + mi->input_gpios == NULL || + mi->output_gpios == NULL) { + err = -ENODEV; + pr_err("gpiomatrix: Incomplete pdata\n"); + goto err_invalid_platform_data; + } + key_count = mi->ninputs * mi->noutputs; + + *data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) * + BITS_TO_LONGS(key_count), GFP_KERNEL); + if (kp == NULL) { + err = -ENOMEM; + pr_err("gpiomatrix: Failed to allocate private data\n"); + goto err_kp_alloc_failed; + } + kp->input_dev = input_dev; + kp->keypad_info = mi; + set_bit(EV_KEY, input_dev->evbit); + for (i = 0; i < key_count; i++) { + if (mi->keymap[i]) + set_bit(mi->keymap[i] & KEY_MAX, + input_dev->keybit); + } + + for (i = 0; i < mi->noutputs; i++) { + if (gpio_cansleep(mi->output_gpios[i])) { + pr_err("gpiomatrix: unsupported output gpio %d," + " can sleep\n", mi->output_gpios[i]); + err = -EINVAL; + goto err_request_output_gpio_failed; + } + err = gpio_request(mi->output_gpios[i], "gpio_kp_out"); + if (err) { + pr_err("gpiomatrix: gpio_request failed for " + "output %d\n", mi->output_gpios[i]); + goto err_request_output_gpio_failed; + } + if (mi->flags & GPIOKPF_DRIVE_INACTIVE) + err = gpio_direction_output(mi->output_gpios[i], + !(mi->flags & GPIOKPF_ACTIVE_HIGH)); + else + err = gpio_direction_input(mi->output_gpios[i]); + if (err) { + pr_err("gpiomatrix: gpio_configure failed for " + "output %d\n", mi->output_gpios[i]); + goto err_output_gpio_configure_failed; + } + } + for (i = 0; i < mi->ninputs; i++) { + err = gpio_request(mi->input_gpios[i], "gpio_kp_in"); + if (err) { + pr_err("gpiomatrix: gpio_request failed for " + "input %d\n", mi->input_gpios[i]); + goto err_request_input_gpio_failed; + } + err = gpio_direction_input(mi->input_gpios[i]); + if (err) { + pr_err("gpiomatrix: gpio_direction_input failed" + " for input %d\n", mi->input_gpios[i]); + goto err_gpio_direction_input_failed; + } + } + kp->current_output = mi->noutputs; + kp->key_state_changed = 1; + + hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + kp->timer.function = gpio_keypad_timer_func; + err = gpio_keypad_request_irqs(kp); + kp->use_irq = err == 0; + + pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for %s " + "in %s mode\n", input_dev->name, + kp->use_irq ? "interrupt" : "polling"); + + hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL); + + return 0; + } + + err = 0; + kp = *data; + + if (kp->use_irq) + for (i = mi->noutputs - 1; i >= 0; i--) + free_irq(gpio_to_irq(mi->input_gpios[i]), kp); + + hrtimer_cancel(&kp->timer); + for (i = mi->noutputs - 1; i >= 0; i--) { +err_gpio_direction_input_failed: + gpio_free(mi->input_gpios[i]); +err_request_input_gpio_failed: + ; + } + for (i = mi->noutputs - 1; i >= 0; i--) { +err_output_gpio_configure_failed: + gpio_free(mi->output_gpios[i]); +err_request_output_gpio_failed: + ; + } + kfree(kp); +err_kp_alloc_failed: +err_invalid_platform_data: + return err; +} diff --git a/trunk/drivers/staging/dream/gpio_output.c b/trunk/drivers/staging/dream/gpio_output.c new file mode 100644 index 000000000000..6f8453c97bd2 --- /dev/null +++ b/trunk/drivers/staging/dream/gpio_output.c @@ -0,0 +1,84 @@ +/* drivers/input/misc/gpio_output.c + * + * Copyright (C) 2007 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include + +int gpio_event_output_event( + struct input_dev *input_dev, struct gpio_event_info *info, void **data, + unsigned int type, unsigned int code, int value) +{ + int i; + struct gpio_event_output_info *oi; + oi = container_of(info, struct gpio_event_output_info, info); + if (type != oi->type) + return 0; + if (!(oi->flags & GPIOEDF_ACTIVE_HIGH)) + value = !value; + for (i = 0; i < oi->keymap_size; i++) + if (code == oi->keymap[i].code) + gpio_set_value(oi->keymap[i].gpio, value); + return 0; +} + +int gpio_event_output_func( + struct input_dev *input_dev, struct gpio_event_info *info, void **data, + int func) +{ + int ret; + int i; + struct gpio_event_output_info *oi; + oi = container_of(info, struct gpio_event_output_info, info); + + if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) + return 0; + + if (func == GPIO_EVENT_FUNC_INIT) { + int output_level = !(oi->flags & GPIOEDF_ACTIVE_HIGH); + for (i = 0; i < oi->keymap_size; i++) + input_set_capability(input_dev, oi->type, + oi->keymap[i].code); + + for (i = 0; i < oi->keymap_size; i++) { + ret = gpio_request(oi->keymap[i].gpio, + "gpio_event_output"); + if (ret) { + pr_err("gpio_event_output_func: gpio_request " + "failed for %d\n", oi->keymap[i].gpio); + goto err_gpio_request_failed; + } + ret = gpio_direction_output(oi->keymap[i].gpio, + output_level); + if (ret) { + pr_err("gpio_event_output_func: " + "gpio_direction_output failed for %d\n", + oi->keymap[i].gpio); + goto err_gpio_direction_output_failed; + } + } + return 0; + } + + ret = 0; + for (i = oi->keymap_size - 1; i >= 0; i--) { +err_gpio_direction_output_failed: + gpio_free(oi->keymap[i].gpio); +err_gpio_request_failed: + ; + } + return ret; +} + diff --git a/trunk/drivers/staging/dream/include/linux/android_pmem.h b/trunk/drivers/staging/dream/include/linux/android_pmem.h new file mode 100644 index 000000000000..2fc05d7d335b --- /dev/null +++ b/trunk/drivers/staging/dream/include/linux/android_pmem.h @@ -0,0 +1,80 @@ +/* drivers/staging/dream/include/linux/android_pmem.h + * + * Copyright (C) 2007 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _ANDROID_PMEM_H_ +#define _ANDROID_PMEM_H_ + +#define PMEM_IOCTL_MAGIC 'p' +#define PMEM_GET_PHYS _IOW(PMEM_IOCTL_MAGIC, 1, unsigned int) +#define PMEM_MAP _IOW(PMEM_IOCTL_MAGIC, 2, unsigned int) +#define PMEM_GET_SIZE _IOW(PMEM_IOCTL_MAGIC, 3, unsigned int) +#define PMEM_UNMAP _IOW(PMEM_IOCTL_MAGIC, 4, unsigned int) +/* This ioctl will allocate pmem space, backing the file, it will fail + * if the file already has an allocation, pass it the len as the argument + * to the ioctl */ +#define PMEM_ALLOCATE _IOW(PMEM_IOCTL_MAGIC, 5, unsigned int) +/* This will connect a one pmem file to another, pass the file that is already + * backed in memory as the argument to the ioctl + */ +#define PMEM_CONNECT _IOW(PMEM_IOCTL_MAGIC, 6, unsigned int) +/* Returns the total size of the pmem region it is sent to as a pmem_region + * struct (with offset set to 0). + */ +#define PMEM_GET_TOTAL_SIZE _IOW(PMEM_IOCTL_MAGIC, 7, unsigned int) +/* Revokes gpu registers and resets the gpu. Pass a pointer to the + * start of the mapped gpu regs (the vaddr returned by mmap) as the argument. + */ +#define HW3D_REVOKE_GPU _IOW(PMEM_IOCTL_MAGIC, 8, unsigned int) +#define HW3D_GRANT_GPU _IOW(PMEM_IOCTL_MAGIC, 9, unsigned int) +#define HW3D_WAIT_FOR_INTERRUPT _IOW(PMEM_IOCTL_MAGIC, 10, unsigned int) + +int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart, + unsigned long *end, struct file **filp); +int get_pmem_user_addr(struct file *file, unsigned long *start, + unsigned long *end); +void put_pmem_file(struct file* file); +void flush_pmem_file(struct file *file, unsigned long start, unsigned long len); + +struct android_pmem_platform_data +{ + const char* name; + /* starting physical address of memory region */ + unsigned long start; + /* size of memory region */ + unsigned long size; + /* set to indicate the region should not be managed with an allocator */ + unsigned no_allocator; + /* set to indicate maps of this region should be cached, if a mix of + * cached and uncached is desired, set this and open the device with + * O_SYNC to get an uncached region */ + unsigned cached; + /* The MSM7k has bits to enable a write buffer in the bus controller*/ + unsigned buffered; +}; + +struct pmem_region { + unsigned long offset; + unsigned long len; +}; + +int pmem_setup(struct android_pmem_platform_data *pdata, + long (*ioctl)(struct file *, unsigned int, unsigned long), + int (*release)(struct inode *, struct file *)); + +int pmem_remap(struct pmem_region *region, struct file *file, + unsigned operation); + +#endif //_ANDROID_PPP_H_ + diff --git a/trunk/drivers/staging/dream/include/linux/gpio_event.h b/trunk/drivers/staging/dream/include/linux/gpio_event.h new file mode 100644 index 000000000000..ffc5da392ad7 --- /dev/null +++ b/trunk/drivers/staging/dream/include/linux/gpio_event.h @@ -0,0 +1,154 @@ +/* drivers/staging/dream/include/linux/gpio_event.h + * + * Copyright (C) 2007 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _LINUX_GPIO_EVENT_H +#define _LINUX_GPIO_EVENT_H + +#include + +enum { + GPIO_EVENT_FUNC_UNINIT = 0x0, + GPIO_EVENT_FUNC_INIT = 0x1, + GPIO_EVENT_FUNC_SUSPEND = 0x2, + GPIO_EVENT_FUNC_RESUME = 0x3, +}; +struct gpio_event_info { + int (*func)(struct input_dev *input_dev, + struct gpio_event_info *info, + void **data, int func); + int (*event)(struct input_dev *input_dev, + struct gpio_event_info *info, + void **data, unsigned int type, + unsigned int code, int value); /* out events */ +}; + +struct gpio_event_platform_data { + const char *name; + struct gpio_event_info **info; + size_t info_count; + int (*power)(const struct gpio_event_platform_data *pdata, bool on); +}; + +#define GPIO_EVENT_DEV_NAME "gpio-event" + +/* Key matrix */ + +enum gpio_event_matrix_flags { + /* unset: drive active output low, set: drive active output high */ + GPIOKPF_ACTIVE_HIGH = 1U << 0, + GPIOKPF_DEBOUNCE = 1U << 1, + GPIOKPF_REMOVE_SOME_PHANTOM_KEYS = 1U << 2, + GPIOKPF_REMOVE_PHANTOM_KEYS = GPIOKPF_REMOVE_SOME_PHANTOM_KEYS | + GPIOKPF_DEBOUNCE, + GPIOKPF_DRIVE_INACTIVE = 1U << 3, + GPIOKPF_LEVEL_TRIGGERED_IRQ = 1U << 4, + GPIOKPF_PRINT_UNMAPPED_KEYS = 1U << 16, + GPIOKPF_PRINT_MAPPED_KEYS = 1U << 17, + GPIOKPF_PRINT_PHANTOM_KEYS = 1U << 18, +}; + +extern int gpio_event_matrix_func(struct input_dev *input_dev, + struct gpio_event_info *info, void **data, int func); +struct gpio_event_matrix_info { + /* initialize to gpio_event_matrix_func */ + struct gpio_event_info info; + /* size must be ninputs * noutputs */ + const unsigned short *keymap; + unsigned int *input_gpios; + unsigned int *output_gpios; + unsigned int ninputs; + unsigned int noutputs; + /* time to wait before reading inputs after driving each output */ + ktime_t settle_time; + /* time to wait before scanning the keypad a second time */ + ktime_t debounce_delay; + ktime_t poll_time; + unsigned flags; +}; + +/* Directly connected inputs and outputs */ + +enum gpio_event_direct_flags { + GPIOEDF_ACTIVE_HIGH = 1U << 0, +/* GPIOEDF_USE_DOWN_IRQ = 1U << 1, */ +/* GPIOEDF_USE_IRQ = (1U << 2) | GPIOIDF_USE_DOWN_IRQ, */ + GPIOEDF_PRINT_KEYS = 1U << 8, + GPIOEDF_PRINT_KEY_DEBOUNCE = 1U << 9, +}; + +struct gpio_event_direct_entry { + uint32_t gpio:23; + uint32_t code:9; +}; + +/* inputs */ +extern int gpio_event_input_func(struct input_dev *input_dev, + struct gpio_event_info *info, void **data, int func); +struct gpio_event_input_info { + /* initialize to gpio_event_input_func */ + struct gpio_event_info info; + ktime_t debounce_time; + ktime_t poll_time; + uint16_t flags; + uint16_t type; + const struct gpio_event_direct_entry *keymap; + size_t keymap_size; +}; + +/* outputs */ +extern int gpio_event_output_func(struct input_dev *input_dev, + struct gpio_event_info *info, void **data, int func); +extern int gpio_event_output_event(struct input_dev *input_dev, + struct gpio_event_info *info, void **data, + unsigned int type, unsigned int code, int value); +struct gpio_event_output_info { + /* initialize to gpio_event_output_func and gpio_event_output_event */ + struct gpio_event_info info; + uint16_t flags; + uint16_t type; + const struct gpio_event_direct_entry *keymap; + size_t keymap_size; +}; + + +/* axes */ + +enum gpio_event_axis_flags { + GPIOEAF_PRINT_UNKNOWN_DIRECTION = 1U << 16, + GPIOEAF_PRINT_RAW = 1U << 17, + GPIOEAF_PRINT_EVENT = 1U << 18, +}; + +extern int gpio_event_axis_func(struct input_dev *input_dev, + struct gpio_event_info *info, void **data, int func); +struct gpio_event_axis_info { + /* initialize to gpio_event_axis_func */ + struct gpio_event_info info; + uint8_t count; + uint8_t type; /* EV_REL or EV_ABS */ + uint16_t code; + uint16_t decoded_size; + uint16_t (*map)(struct gpio_event_axis_info *info, uint16_t in); + uint32_t *gpio; + uint32_t flags; +}; +#define gpio_axis_2bit_gray_map gpio_axis_4bit_gray_map +#define gpio_axis_3bit_gray_map gpio_axis_4bit_gray_map +uint16_t gpio_axis_4bit_gray_map( + struct gpio_event_axis_info *info, uint16_t in); +uint16_t gpio_axis_5bit_singletrack_map( + struct gpio_event_axis_info *info, uint16_t in); + +#endif diff --git a/trunk/drivers/staging/dream/include/linux/msm_adsp.h b/trunk/drivers/staging/dream/include/linux/msm_adsp.h new file mode 100644 index 000000000000..e775f3e94f1d --- /dev/null +++ b/trunk/drivers/staging/dream/include/linux/msm_adsp.h @@ -0,0 +1,84 @@ +/* drivers/staging/dream/include/linux/msm_adsp.h + * + * Copyright (c) QUALCOMM Incorporated + * Copyright (C) 2007 Google, Inc. + * Author: Iliyan Malchev + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef __LINUX_MSM_ADSP_H +#define __LINUX_MSM_ADSP_H + +#include +#include + +#define ADSP_IOCTL_MAGIC 'q' + +/* ADSP_IOCTL_WRITE_COMMAND */ +struct adsp_command_t { + uint16_t queue; + uint32_t len; /* bytes */ + uint8_t *data; +}; + +/* ADSP_IOCTL_GET_EVENT */ +struct adsp_event_t { + uint16_t type; /* 1 == event (RPC), 0 == message (adsp) */ + uint32_t timeout_ms; /* -1 for infinite, 0 for immediate return */ + uint16_t msg_id; + uint16_t flags; /* 1 == 16--bit event, 0 == 32-bit event */ + uint32_t len; /* size in, number of bytes out */ + uint8_t *data; +}; + +#define ADSP_IOCTL_ENABLE \ + _IOR(ADSP_IOCTL_MAGIC, 1, unsigned) + +#define ADSP_IOCTL_DISABLE \ + _IOR(ADSP_IOCTL_MAGIC, 2, unsigned) + +#define ADSP_IOCTL_DISABLE_ACK \ + _IOR(ADSP_IOCTL_MAGIC, 3, unsigned) + +#define ADSP_IOCTL_WRITE_COMMAND \ + _IOR(ADSP_IOCTL_MAGIC, 4, struct adsp_command_t *) + +#define ADSP_IOCTL_GET_EVENT \ + _IOWR(ADSP_IOCTL_MAGIC, 5, struct adsp_event_data_t *) + +#define ADSP_IOCTL_SET_CLKRATE \ + _IOR(ADSP_IOCTL_MAGIC, 6, unsigned) + +#define ADSP_IOCTL_DISABLE_EVENT_RSP \ + _IOR(ADSP_IOCTL_MAGIC, 10, unsigned) + +struct adsp_pmem_info { + int fd; + void *vaddr; +}; + +#define ADSP_IOCTL_REGISTER_PMEM \ + _IOW(ADSP_IOCTL_MAGIC, 13, unsigned) + +#define ADSP_IOCTL_UNREGISTER_PMEM \ + _IOW(ADSP_IOCTL_MAGIC, 14, unsigned) + +/* Cause any further GET_EVENT ioctls to fail (-ENODEV) + * until the device is closed and reopened. Useful for + * terminating event dispatch threads + */ +#define ADSP_IOCTL_ABORT_EVENT_READ \ + _IOW(ADSP_IOCTL_MAGIC, 15, unsigned) + +#define ADSP_IOCTL_LINK_TASK \ + _IOW(ADSP_IOCTL_MAGIC, 16, unsigned) + +#endif diff --git a/trunk/drivers/staging/dream/include/linux/msm_audio.h b/trunk/drivers/staging/dream/include/linux/msm_audio.h new file mode 100644 index 000000000000..cfbdaa0d98b2 --- /dev/null +++ b/trunk/drivers/staging/dream/include/linux/msm_audio.h @@ -0,0 +1,115 @@ +/* drivers/staging/dream/include/linux/msm_audio.h + * + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __LINUX_MSM_AUDIO_H +#define __LINUX_MSM_AUDIO_H + +#include +#include +#include + +/* PCM Audio */ + +#define AUDIO_IOCTL_MAGIC 'a' + +#define AUDIO_START _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned) +#define AUDIO_STOP _IOW(AUDIO_IOCTL_MAGIC, 1, unsigned) +#define AUDIO_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 2, unsigned) +#define AUDIO_GET_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 3, unsigned) +#define AUDIO_SET_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 4, unsigned) +#define AUDIO_GET_STATS _IOR(AUDIO_IOCTL_MAGIC, 5, unsigned) +#define AUDIO_ENABLE_AUDPP _IOW(AUDIO_IOCTL_MAGIC, 6, unsigned) +#define AUDIO_SET_ADRC _IOW(AUDIO_IOCTL_MAGIC, 7, unsigned) +#define AUDIO_SET_EQ _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned) +#define AUDIO_SET_RX_IIR _IOW(AUDIO_IOCTL_MAGIC, 9, unsigned) +#define AUDIO_SET_VOLUME _IOW(AUDIO_IOCTL_MAGIC, 10, unsigned) +#define AUDIO_ENABLE_AUDPRE _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned) +#define AUDIO_SET_AGC _IOW(AUDIO_IOCTL_MAGIC, 12, unsigned) +#define AUDIO_SET_NS _IOW(AUDIO_IOCTL_MAGIC, 13, unsigned) +#define AUDIO_SET_TX_IIR _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned) +#define AUDIO_PAUSE _IOW(AUDIO_IOCTL_MAGIC, 15, unsigned) +#define AUDIO_GET_PCM_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 30, unsigned) +#define AUDIO_SET_PCM_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 31, unsigned) +#define AUDIO_SWITCH_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 32, unsigned) + +#define AUDIO_MAX_COMMON_IOCTL_NUM 100 + +#define AUDIO_MAX_COMMON_IOCTL_NUM 100 + +struct msm_audio_config { + uint32_t buffer_size; + uint32_t buffer_count; + uint32_t channel_count; + uint32_t sample_rate; + uint32_t type; + uint32_t unused[3]; +}; + +struct msm_audio_stats { + uint32_t byte_count; + uint32_t sample_count; + uint32_t unused[2]; +}; + +/* Audio routing */ + +#define SND_IOCTL_MAGIC 's' + +#define SND_MUTE_UNMUTED 0 +#define SND_MUTE_MUTED 1 + +struct msm_snd_device_config { + uint32_t device; + uint32_t ear_mute; + uint32_t mic_mute; +}; + +#define SND_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_device_config *) + +#define SND_METHOD_VOICE 0 + +struct msm_snd_volume_config { + uint32_t device; + uint32_t method; + uint32_t volume; +}; + +#define SND_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_snd_volume_config *) + +/* Returns the number of SND endpoints supported. */ + +#define SND_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *) + +struct msm_snd_endpoint { + int id; /* input and output */ + char name[64]; /* output only */ +}; + +/* Takes an index between 0 and one less than the number returned by + * SND_GET_NUM_ENDPOINTS, and returns the SND index and name of a + * SND endpoint. On input, the .id field contains the number of the + * endpoint, and on exit it contains the SND index, while .name contains + * the description of the endpoint. + */ + +#define SND_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct msm_snd_endpoint *) + +struct msm_audio_pcm_config { + uint32_t pcm_feedback; /* 0 - disable > 0 - enable */ + uint32_t buffer_count; /* Number of buffers to allocate */ + uint32_t buffer_size; /* Size of buffer for capturing of + PCM samples */ +}; +#endif diff --git a/trunk/drivers/staging/dream/include/linux/msm_rpcrouter.h b/trunk/drivers/staging/dream/include/linux/msm_rpcrouter.h new file mode 100644 index 000000000000..64845fb481f1 --- /dev/null +++ b/trunk/drivers/staging/dream/include/linux/msm_rpcrouter.h @@ -0,0 +1,47 @@ +/* drivers/staging/dream/include/linux/msm_rpcrouter.h + * + * Copyright (c) QUALCOMM Incorporated + * Copyright (C) 2007 Google, Inc. + * Author: San Mehat + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef __LINUX_MSM_RPCROUTER_H +#define __LINUX_MSM_RPCROUTER_H + +#include +#include + +#define RPC_ROUTER_VERSION_V1 0x00010000 + +struct rpcrouter_ioctl_server_args { + uint32_t prog; + uint32_t vers; +}; + +#define RPC_ROUTER_IOCTL_MAGIC (0xC1) + +#define RPC_ROUTER_IOCTL_GET_VERSION \ + _IOR(RPC_ROUTER_IOCTL_MAGIC, 0, unsigned int) + +#define RPC_ROUTER_IOCTL_GET_MTU \ + _IOR(RPC_ROUTER_IOCTL_MAGIC, 1, unsigned int) + +#define RPC_ROUTER_IOCTL_REGISTER_SERVER \ + _IOWR(RPC_ROUTER_IOCTL_MAGIC, 2, unsigned int) + +#define RPC_ROUTER_IOCTL_UNREGISTER_SERVER \ + _IOWR(RPC_ROUTER_IOCTL_MAGIC, 3, unsigned int) + +#define RPC_ROUTER_IOCTL_GET_MINOR_VERSION \ + _IOW(RPC_ROUTER_IOCTL_MAGIC, 4, unsigned int) + +#endif diff --git a/trunk/drivers/staging/dream/include/linux/wakelock.h b/trunk/drivers/staging/dream/include/linux/wakelock.h new file mode 100644 index 000000000000..93c31a4d1ca7 --- /dev/null +++ b/trunk/drivers/staging/dream/include/linux/wakelock.h @@ -0,0 +1,91 @@ +/* drivers/staging/dream/include/linux/wakelock.h + * + * Copyright (C) 2007-2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _LINUX_WAKELOCK_H +#define _LINUX_WAKELOCK_H + +#include +#include + +/* A wake_lock prevents the system from entering suspend or other low power + * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock + * prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low power + * states that cause large interrupt latencies or that disable a set of + * interrupts will not entered from idle until the wake_locks are released. + */ + +enum { + WAKE_LOCK_SUSPEND, /* Prevent suspend */ + WAKE_LOCK_IDLE, /* Prevent low power idle */ + WAKE_LOCK_TYPE_COUNT +}; + +struct wake_lock { +#ifdef CONFIG_HAS_WAKELOCK + struct list_head link; + int flags; + const char *name; + unsigned long expires; +#ifdef CONFIG_WAKELOCK_STAT + struct { + int count; + int expire_count; + int wakeup_count; + ktime_t total_time; + ktime_t prevent_suspend_time; + ktime_t max_time; + ktime_t last_time; + } stat; +#endif +#endif +}; + +#ifdef CONFIG_HAS_WAKELOCK + +void wake_lock_init(struct wake_lock *lock, int type, const char *name); +void wake_lock_destroy(struct wake_lock *lock); +void wake_lock(struct wake_lock *lock); +void wake_lock_timeout(struct wake_lock *lock, long timeout); +void wake_unlock(struct wake_lock *lock); + +/* wake_lock_active returns a non-zero value if the wake_lock is currently + * locked. If the wake_lock has a timeout, it does not check the timeout + * but if the timeout had aready been checked it will return 0. + */ +int wake_lock_active(struct wake_lock *lock); + +/* has_wake_lock returns 0 if no wake locks of the specified type are active, + * and non-zero if one or more wake locks are held. Specifically it returns + * -1 if one or more wake locks with no timeout are active or the + * number of jiffies until all active wake locks time out. + */ +long has_wake_lock(int type); + +#else + +static inline void wake_lock_init(struct wake_lock *lock, int type, + const char *name) {} +static inline void wake_lock_destroy(struct wake_lock *lock) {} +static inline void wake_lock(struct wake_lock *lock) {} +static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) {} +static inline void wake_unlock(struct wake_lock *lock) {} + +static inline int wake_lock_active(struct wake_lock *lock) { return 0; } +static inline long has_wake_lock(int type) { return 0; } + +#endif + +#endif + diff --git a/trunk/drivers/staging/dream/include/mach/camera.h b/trunk/drivers/staging/dream/include/mach/camera.h new file mode 100644 index 000000000000..c20f0423abd4 --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/camera.h @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ + +#ifndef __ASM__ARCH_CAMERA_H +#define __ASM__ARCH_CAMERA_H + +#include +#include +#include +#include +#include "linux/types.h" + +#include +#include + +#ifdef CONFIG_MSM_CAMERA_DEBUG +#define CDBG(fmt, args...) printk(KERN_INFO "msm_camera: " fmt, ##args) +#else +#define CDBG(fmt, args...) do { } while (0) +#endif + +#define MSM_CAMERA_MSG 0 +#define MSM_CAMERA_EVT 1 +#define NUM_WB_EXP_NEUTRAL_REGION_LINES 4 +#define NUM_WB_EXP_STAT_OUTPUT_BUFFERS 3 +#define NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS 16 +#define NUM_AF_STAT_OUTPUT_BUFFERS 3 + +enum msm_queue { + MSM_CAM_Q_CTRL, /* control command or control command status */ + MSM_CAM_Q_VFE_EVT, /* adsp event */ + MSM_CAM_Q_VFE_MSG, /* adsp message */ + MSM_CAM_Q_V4L2_REQ, /* v4l2 request */ +}; + +enum vfe_resp_msg { + VFE_EVENT, + VFE_MSG_GENERAL, + VFE_MSG_SNAPSHOT, + VFE_MSG_OUTPUT1, + VFE_MSG_OUTPUT2, + VFE_MSG_STATS_AF, + VFE_MSG_STATS_WE, +}; + +struct msm_vfe_phy_info { + uint32_t sbuf_phy; + uint32_t y_phy; + uint32_t cbcr_phy; +}; + +struct msm_vfe_resp { + enum vfe_resp_msg type; + struct msm_vfe_evt_msg evt_msg; + struct msm_vfe_phy_info phy; + void *extdata; + int32_t extlen; +}; + +struct msm_vfe_callback { + void (*vfe_resp)(struct msm_vfe_resp *, + enum msm_queue, void *syncdata); + void* (*vfe_alloc)(int, void *syncdata); +}; + +struct msm_camvfe_fn { + int (*vfe_init)(struct msm_vfe_callback *, struct platform_device *); + int (*vfe_enable)(struct camera_enable_cmd *); + int (*vfe_config)(struct msm_vfe_cfg_cmd *, void *); + int (*vfe_disable)(struct camera_enable_cmd *, + struct platform_device *dev); + void (*vfe_release)(struct platform_device *); +}; + +struct msm_sensor_ctrl { + int (*s_init)(const struct msm_camera_sensor_info *); + int (*s_release)(void); + int (*s_config)(void __user *); +}; + +struct msm_sync { + /* These two queues are accessed from a process context only. */ + struct hlist_head frame; /* most-frequently accessed */ + struct hlist_head stats; + + /* The message queue is used by the control thread to send commands + * to the config thread, and also by the DSP to send messages to the + * config thread. Thus it is the only queue that is accessed from + * both interrupt and process context. + */ + spinlock_t msg_event_q_lock; + struct list_head msg_event_q; + wait_queue_head_t msg_event_wait; + + /* This queue contains preview frames. It is accessed by the DSP (in + * in interrupt context, and by the frame thread. + */ + spinlock_t prev_frame_q_lock; + struct list_head prev_frame_q; + wait_queue_head_t prev_frame_wait; + int unblock_poll_frame; + + /* This queue contains snapshot frames. It is accessed by the DSP (in + * interrupt context, and by the control thread. + */ + spinlock_t pict_frame_q_lock; + struct list_head pict_frame_q; + wait_queue_head_t pict_frame_wait; + + struct msm_camera_sensor_info *sdata; + struct msm_camvfe_fn vfefn; + struct msm_sensor_ctrl sctrl; + struct platform_device *pdev; + uint8_t opencnt; + void *cropinfo; + int croplen; + unsigned pict_pp; + + const char *apps_id; + + struct mutex lock; + struct list_head list; +}; + +#define MSM_APPS_ID_V4L2 "msm_v4l2" +#define MSM_APPS_ID_PROP "msm_qct" + +struct msm_device { + struct msm_sync *sync; /* most-frequently accessed */ + struct device *device; + struct cdev cdev; + /* opened is meaningful only for the config and frame nodes, + * which may be opened only once. + */ + atomic_t opened; +}; + +struct msm_control_device_queue { + spinlock_t ctrl_status_q_lock; + struct list_head ctrl_status_q; + wait_queue_head_t ctrl_status_wait; +}; + +struct msm_control_device { + struct msm_device *pmsm; + + /* This queue used by the config thread to send responses back to the + * control thread. It is accessed only from a process context. + */ + struct msm_control_device_queue ctrl_q; +}; + +/* this structure is used in kernel */ +struct msm_queue_cmd { + struct list_head list; + enum msm_queue type; + void *command; +}; + +struct register_address_value_pair { + uint16_t register_address; + uint16_t register_value; +}; + +struct msm_pmem_region { + struct hlist_node list; + int type; + void *vaddr; + unsigned long paddr; + unsigned long len; + struct file *file; + uint32_t y_off; + uint32_t cbcr_off; + int fd; + uint8_t active; +}; + +struct axidata { + uint32_t bufnum1; + uint32_t bufnum2; + struct msm_pmem_region *region; +}; + +#ifdef CONFIG_MSM_CAMERA_FLASH +int msm_camera_flash_set_led_state(unsigned led_state); +#else +static inline int msm_camera_flash_set_led_state(unsigned led_state) +{ + return -ENOTSUPP; +} +#endif + +/* Below functions are added for V4L2 kernel APIs */ +struct msm_v4l2_driver { + struct msm_sync *sync; + int (*open)(struct msm_sync *, const char *apps_id); + int (*release)(struct msm_sync *); + int (*ctrl)(struct msm_sync *, struct msm_ctrl_cmd *); + int (*reg_pmem)(struct msm_sync *, struct msm_pmem_info *); + int (*get_frame) (struct msm_sync *, struct msm_frame *); + int (*put_frame) (struct msm_sync *, struct msm_frame *); + int (*get_pict) (struct msm_sync *, struct msm_ctrl_cmd *); + unsigned int (*drv_poll) (struct msm_sync *, struct file *, + struct poll_table_struct *); +}; + +int msm_v4l2_register(struct msm_v4l2_driver *); +int msm_v4l2_unregister(struct msm_v4l2_driver *); + +void msm_camvfe_init(void); +int msm_camvfe_check(void *); +void msm_camvfe_fn_init(struct msm_camvfe_fn *, void *); +int msm_camera_drv_start(struct platform_device *dev, + int (*sensor_probe)(const struct msm_camera_sensor_info *, + struct msm_sensor_ctrl *)); + +enum msm_camio_clk_type { + CAMIO_VFE_MDC_CLK, + CAMIO_MDC_CLK, + CAMIO_VFE_CLK, + CAMIO_VFE_AXI_CLK, + + CAMIO_MAX_CLK +}; + +enum msm_camio_clk_src_type { + MSM_CAMIO_CLK_SRC_INTERNAL, + MSM_CAMIO_CLK_SRC_EXTERNAL, + MSM_CAMIO_CLK_SRC_MAX +}; + +enum msm_s_test_mode { + S_TEST_OFF, + S_TEST_1, + S_TEST_2, + S_TEST_3 +}; + +enum msm_s_resolution { + S_QTR_SIZE, + S_FULL_SIZE, + S_INVALID_SIZE +}; + +enum msm_s_reg_update { + /* Sensor egisters that need to be updated during initialization */ + S_REG_INIT, + /* Sensor egisters that needs periodic I2C writes */ + S_UPDATE_PERIODIC, + /* All the sensor Registers will be updated */ + S_UPDATE_ALL, + /* Not valid update */ + S_UPDATE_INVALID +}; + +enum msm_s_setting { + S_RES_PREVIEW, + S_RES_CAPTURE +}; + +int msm_camio_enable(struct platform_device *dev); + +int msm_camio_clk_enable(enum msm_camio_clk_type clk); +int msm_camio_clk_disable(enum msm_camio_clk_type clk); +int msm_camio_clk_config(uint32_t freq); +void msm_camio_clk_rate_set(int rate); +void msm_camio_clk_axi_rate_set(int rate); + +void msm_camio_camif_pad_reg_reset(void); +void msm_camio_camif_pad_reg_reset_2(void); + +void msm_camio_vfe_blk_reset(void); + +void msm_camio_clk_sel(enum msm_camio_clk_src_type); +void msm_camio_disable(struct platform_device *); +int msm_camio_probe_on(struct platform_device *); +int msm_camio_probe_off(struct platform_device *); +#endif diff --git a/trunk/drivers/staging/dream/include/mach/msm_adsp.h b/trunk/drivers/staging/dream/include/mach/msm_adsp.h new file mode 100644 index 000000000000..a081683328a3 --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/msm_adsp.h @@ -0,0 +1,112 @@ +/* include/asm-arm/arch-msm/msm_adsp.h + * + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __ASM__ARCH_MSM_ADSP_H +#define __ASM__ARCH_MSM_ADSP_H + +struct msm_adsp_module; + +struct msm_adsp_ops { + /* event is called from interrupt context when a message + * arrives from the DSP. Use the provided function pointer + * to copy the message into a local buffer. Do NOT call + * it multiple times. + */ + void (*event)(void *driver_data, unsigned id, size_t len, + void (*getevent)(void *ptr, size_t len)); +}; + +/* Get, Put, Enable, and Disable are synchronous and must only + * be called from thread context. Enable and Disable will block + * up to one second in the event of a fatal DSP error but are + * much faster otherwise. + */ +int msm_adsp_get(const char *name, struct msm_adsp_module **module, + struct msm_adsp_ops *ops, void *driver_data); +void msm_adsp_put(struct msm_adsp_module *module); +int msm_adsp_enable(struct msm_adsp_module *module); +int msm_adsp_disable(struct msm_adsp_module *module); +int adsp_set_clkrate(struct msm_adsp_module *module, unsigned long clk_rate); + +/* Write is safe to call from interrupt context. + */ +int msm_adsp_write(struct msm_adsp_module *module, + unsigned queue_id, + void *data, size_t len); + +#if CONFIG_MSM_AMSS_VERSION >= 6350 +/* Command Queue Indexes */ +#define QDSP_lpmCommandQueue 0 +#define QDSP_mpuAfeQueue 1 +#define QDSP_mpuGraphicsCmdQueue 2 +#define QDSP_mpuModmathCmdQueue 3 +#define QDSP_mpuVDecCmdQueue 4 +#define QDSP_mpuVDecPktQueue 5 +#define QDSP_mpuVEncCmdQueue 6 +#define QDSP_rxMpuDecCmdQueue 7 +#define QDSP_rxMpuDecPktQueue 8 +#define QDSP_txMpuEncQueue 9 +#define QDSP_uPAudPPCmd1Queue 10 +#define QDSP_uPAudPPCmd2Queue 11 +#define QDSP_uPAudPPCmd3Queue 12 +#define QDSP_uPAudPlay0BitStreamCtrlQueue 13 +#define QDSP_uPAudPlay1BitStreamCtrlQueue 14 +#define QDSP_uPAudPlay2BitStreamCtrlQueue 15 +#define QDSP_uPAudPlay3BitStreamCtrlQueue 16 +#define QDSP_uPAudPlay4BitStreamCtrlQueue 17 +#define QDSP_uPAudPreProcCmdQueue 18 +#define QDSP_uPAudRecBitStreamQueue 19 +#define QDSP_uPAudRecCmdQueue 20 +#define QDSP_uPDiagQueue 21 +#define QDSP_uPJpegActionCmdQueue 22 +#define QDSP_uPJpegCfgCmdQueue 23 +#define QDSP_uPVocProcQueue 24 +#define QDSP_vfeCommandQueue 25 +#define QDSP_vfeCommandScaleQueue 26 +#define QDSP_vfeCommandTableQueue 27 +#define QDSP_MAX_NUM_QUEUES 28 +#else +/* Command Queue Indexes */ +#define QDSP_lpmCommandQueue 0 +#define QDSP_mpuAfeQueue 1 +#define QDSP_mpuGraphicsCmdQueue 2 +#define QDSP_mpuModmathCmdQueue 3 +#define QDSP_mpuVDecCmdQueue 4 +#define QDSP_mpuVDecPktQueue 5 +#define QDSP_mpuVEncCmdQueue 6 +#define QDSP_rxMpuDecCmdQueue 7 +#define QDSP_rxMpuDecPktQueue 8 +#define QDSP_txMpuEncQueue 9 +#define QDSP_uPAudPPCmd1Queue 10 +#define QDSP_uPAudPPCmd2Queue 11 +#define QDSP_uPAudPPCmd3Queue 12 +#define QDSP_uPAudPlay0BitStreamCtrlQueue 13 +#define QDSP_uPAudPlay1BitStreamCtrlQueue 14 +#define QDSP_uPAudPlay2BitStreamCtrlQueue 15 +#define QDSP_uPAudPlay3BitStreamCtrlQueue 16 +#define QDSP_uPAudPlay4BitStreamCtrlQueue 17 +#define QDSP_uPAudPreProcCmdQueue 18 +#define QDSP_uPAudRecBitStreamQueue 19 +#define QDSP_uPAudRecCmdQueue 20 +#define QDSP_uPJpegActionCmdQueue 21 +#define QDSP_uPJpegCfgCmdQueue 22 +#define QDSP_uPVocProcQueue 23 +#define QDSP_vfeCommandQueue 24 +#define QDSP_vfeCommandScaleQueue 25 +#define QDSP_vfeCommandTableQueue 26 +#define QDSP_QUEUE_MAX 26 +#endif + +#endif diff --git a/trunk/drivers/staging/dream/include/mach/msm_rpcrouter.h b/trunk/drivers/staging/dream/include/mach/msm_rpcrouter.h new file mode 100644 index 000000000000..9724ece1c97c --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/msm_rpcrouter.h @@ -0,0 +1,179 @@ +/** include/asm-arm/arch-msm/msm_rpcrouter.h + * + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2007-2009 QUALCOMM Incorporated + * Author: San Mehat + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __ASM__ARCH_MSM_RPCROUTER_H +#define __ASM__ARCH_MSM_RPCROUTER_H + +#include +#include +#include + +#if CONFIG_MSM_AMSS_VERSION >= 6350 +/* RPC API version structure + * Version bit 31 : 1->hashkey versioning, + * 0->major-minor (backward compatible) versioning + * hashkey versioning: + * Version bits 31-0 hashkey + * major-minor (backward compatible) versioning + * Version bits 30-28 reserved (no match) + * Version bits 27-16 major (must match) + * Version bits 15-0 minor (greater or equal) + */ +#define RPC_VERSION_MODE_MASK 0x80000000 +#define RPC_VERSION_MAJOR_MASK 0x0fff0000 +#define RPC_VERSION_MAJOR_OFFSET 16 +#define RPC_VERSION_MINOR_MASK 0x0000ffff + +#define MSM_RPC_VERS(major, minor) \ + ((uint32_t)((((major) << RPC_VERSION_MAJOR_OFFSET) & \ + RPC_VERSION_MAJOR_MASK) | \ + ((minor) & RPC_VERSION_MINOR_MASK))) +#define MSM_RPC_GET_MAJOR(vers) (((vers) & RPC_VERSION_MAJOR_MASK) >> \ + RPC_VERSION_MAJOR_OFFSET) +#define MSM_RPC_GET_MINOR(vers) ((vers) & RPC_VERSION_MINOR_MASK) +#else +#define MSM_RPC_VERS(major, minor) (major) +#define MSM_RPC_GET_MAJOR(vers) (vers) +#define MSM_RPC_GET_MINOR(vers) 0 +#endif + +struct msm_rpc_endpoint; + +struct rpcsvr_platform_device +{ + struct platform_device base; + uint32_t prog; + uint32_t vers; +}; + +#define RPC_DATA_IN 0 +/* + * Structures for sending / receiving direct RPC requests + * XXX: Any cred/verif lengths > 0 not supported + */ + +struct rpc_request_hdr +{ + uint32_t xid; + uint32_t type; /* 0 */ + uint32_t rpc_vers; /* 2 */ + uint32_t prog; + uint32_t vers; + uint32_t procedure; + uint32_t cred_flavor; + uint32_t cred_length; + uint32_t verf_flavor; + uint32_t verf_length; +}; + +typedef struct +{ + uint32_t low; + uint32_t high; +} rpc_reply_progmismatch_data; + +typedef struct +{ +} rpc_denied_reply_hdr; + +typedef struct +{ + uint32_t verf_flavor; + uint32_t verf_length; + uint32_t accept_stat; +#define RPC_ACCEPTSTAT_SUCCESS 0 +#define RPC_ACCEPTSTAT_PROG_UNAVAIL 1 +#define RPC_ACCEPTSTAT_PROG_MISMATCH 2 +#define RPC_ACCEPTSTAT_PROC_UNAVAIL 3 +#define RPC_ACCEPTSTAT_GARBAGE_ARGS 4 +#define RPC_ACCEPTSTAT_SYSTEM_ERR 5 +#define RPC_ACCEPTSTAT_PROG_LOCKED 6 + /* + * Following data is dependant on accept_stat + * If ACCEPTSTAT == PROG_MISMATCH then there is a + * 'rpc_reply_progmismatch_data' structure following the header. + * Otherwise the data is procedure specific + */ +} rpc_accepted_reply_hdr; + +struct rpc_reply_hdr +{ + uint32_t xid; + uint32_t type; + uint32_t reply_stat; +#define RPCMSG_REPLYSTAT_ACCEPTED 0 +#define RPCMSG_REPLYSTAT_DENIED 1 + union { + rpc_accepted_reply_hdr acc_hdr; + rpc_denied_reply_hdr dny_hdr; + } data; +}; + +/* flags for msm_rpc_connect() */ +#define MSM_RPC_UNINTERRUPTIBLE 0x0001 + +/* use IS_ERR() to check for failure */ +struct msm_rpc_endpoint *msm_rpc_open(void); +/* Connect with the specified server version */ +struct msm_rpc_endpoint *msm_rpc_connect(uint32_t prog, uint32_t vers, unsigned flags); +uint32_t msm_rpc_get_vers(struct msm_rpc_endpoint *ept); +/* check if server version can handle client requested version */ +int msm_rpc_is_compatible_version(uint32_t server_version, + uint32_t client_version); + +int msm_rpc_close(struct msm_rpc_endpoint *ept); +int msm_rpc_write(struct msm_rpc_endpoint *ept, + void *data, int len); +int msm_rpc_read(struct msm_rpc_endpoint *ept, + void **data, unsigned len, long timeout); +void msm_rpc_setup_req(struct rpc_request_hdr *hdr, + uint32_t prog, uint32_t vers, uint32_t proc); +int msm_rpc_register_server(struct msm_rpc_endpoint *ept, + uint32_t prog, uint32_t vers); +int msm_rpc_unregister_server(struct msm_rpc_endpoint *ept, + uint32_t prog, uint32_t vers); + +/* simple blocking rpc call + * + * request is mandatory and must have a rpc_request_hdr + * at the start. The header will be filled out for you. + * + * reply provides a buffer for replies of reply_max_size + */ +int msm_rpc_call_reply(struct msm_rpc_endpoint *ept, uint32_t proc, + void *request, int request_size, + void *reply, int reply_max_size, + long timeout); +int msm_rpc_call(struct msm_rpc_endpoint *ept, uint32_t proc, + void *request, int request_size, + long timeout); + +struct msm_rpc_server +{ + struct list_head list; + uint32_t flags; + + uint32_t prog; + uint32_t vers; + + int (*rpc_call)(struct msm_rpc_server *server, + struct rpc_request_hdr *req, unsigned len); +}; + +int msm_rpc_create_server(struct msm_rpc_server *server); + +#endif diff --git a/trunk/drivers/staging/dream/include/mach/msm_smd.h b/trunk/drivers/staging/dream/include/mach/msm_smd.h new file mode 100644 index 000000000000..bdf7731ab680 --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/msm_smd.h @@ -0,0 +1,107 @@ +/* linux/include/asm-arm/arch-msm/msm_smd.h + * + * Copyright (C) 2007 Google, Inc. + * Author: Brian Swetland + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __ASM_ARCH_MSM_SMD_H +#define __ASM_ARCH_MSM_SMD_H + +typedef struct smd_channel smd_channel_t; + +/* warning: notify() may be called before open returns */ +int smd_open(const char *name, smd_channel_t **ch, void *priv, + void (*notify)(void *priv, unsigned event)); + +#define SMD_EVENT_DATA 1 +#define SMD_EVENT_OPEN 2 +#define SMD_EVENT_CLOSE 3 + +int smd_close(smd_channel_t *ch); + +/* passing a null pointer for data reads and discards */ +int smd_read(smd_channel_t *ch, void *data, int len); + +/* Write to stream channels may do a partial write and return +** the length actually written. +** Write to packet channels will never do a partial write -- +** it will return the requested length written or an error. +*/ +int smd_write(smd_channel_t *ch, const void *data, int len); + +int smd_write_avail(smd_channel_t *ch); +int smd_read_avail(smd_channel_t *ch); + +/* Returns the total size of the current packet being read. +** Returns 0 if no packets available or a stream channel. +*/ +int smd_cur_packet_size(smd_channel_t *ch); + +/* used for tty unthrottling and the like -- causes the notify() +** callback to be called from the same lock context as is used +** when it is called from channel updates +*/ +void smd_kick(smd_channel_t *ch); + + +#if 0 +/* these are interruptable waits which will block you until the specified +** number of bytes are readable or writable. +*/ +int smd_wait_until_readable(smd_channel_t *ch, int bytes); +int smd_wait_until_writable(smd_channel_t *ch, int bytes); +#endif + +typedef enum +{ + SMD_PORT_DS = 0, + SMD_PORT_DIAG, + SMD_PORT_RPC_CALL, + SMD_PORT_RPC_REPLY, + SMD_PORT_BT, + SMD_PORT_CONTROL, + SMD_PORT_MEMCPY_SPARE1, + SMD_PORT_DATA1, + SMD_PORT_DATA2, + SMD_PORT_DATA3, + SMD_PORT_DATA4, + SMD_PORT_DATA5, + SMD_PORT_DATA6, + SMD_PORT_DATA7, + SMD_PORT_DATA8, + SMD_PORT_DATA9, + SMD_PORT_DATA10, + SMD_PORT_DATA11, + SMD_PORT_DATA12, + SMD_PORT_DATA13, + SMD_PORT_DATA14, + SMD_PORT_DATA15, + SMD_PORT_DATA16, + SMD_PORT_DATA17, + SMD_PORT_DATA18, + SMD_PORT_DATA19, + SMD_PORT_DATA20, + SMD_PORT_GPS_NMEA, + SMD_PORT_BRIDGE_1, + SMD_PORT_BRIDGE_2, + SMD_PORT_BRIDGE_3, + SMD_PORT_BRIDGE_4, + SMD_PORT_BRIDGE_5, + SMD_PORT_LOOPBACK, + SMD_PORT_CS_APPS_MODEM, + SMD_PORT_CS_APPS_DSP, + SMD_PORT_CS_MODEM_DSP, + SMD_NUM_PORTS, +} smd_port_id_type; + +#endif diff --git a/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h new file mode 100644 index 000000000000..0b6a31259bb0 --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h @@ -0,0 +1,94 @@ +#ifndef QDSP5AUDPLAYCMDI_H +#define QDSP5AUDPLAYCMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + Q D S P 5 A U D I O P L A Y T A S K C O M M A N D S + +GENERAL DESCRIPTION + Command Interface for AUDPLAYTASK on QDSP5 + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + + audplay_cmd_dec_data_avail + Send buffer to AUDPLAY task + + +Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaycmdi.h#2 $ + +===========================================================================*/ + +#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL 0x0000 +#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_LEN \ + sizeof(audplay_cmd_bitstream_data_avail) + +/* Type specification of dec_data_avail message sent to AUDPLAYTASK +*/ +typedef struct { + /*command ID*/ + unsigned int cmd_id; + + /* Decoder ID for which message is being sent */ + unsigned int decoder_id; + + /* Start address of data in ARM global memory */ + unsigned int buf_ptr; + + /* Number of 16-bit words of bit-stream data contiguously available at the + * above-mentioned address. */ + unsigned int buf_size; + + /* Partition number used by audPlayTask to communicate with DSP's RTOS + * kernel */ + unsigned int partition_number; +} __attribute__((packed)) audplay_cmd_bitstream_data_avail; + +#define AUDPLAY_CMD_HPCM_BUF_CFG 0x0003 +#define AUDPLAY_CMD_HPCM_BUF_CFG_LEN \ + sizeof(struct audplay_cmd_hpcm_buf_cfg) + +struct audplay_cmd_hpcm_buf_cfg { + unsigned int cmd_id; + unsigned int hostpcm_config; + unsigned int feedback_frequency; + unsigned int byte_swap; + unsigned int max_buffers; + unsigned int partition_number; +} __attribute__((packed)); + +#define AUDPLAY_CMD_BUFFER_REFRESH 0x0004 +#define AUDPLAY_CMD_BUFFER_REFRESH_LEN \ + sizeof(struct audplay_cmd_buffer_update) + +struct audplay_cmd_buffer_refresh { + unsigned int cmd_id; + unsigned int num_buffers; + unsigned int buf_read_count; + unsigned int buf0_address; + unsigned int buf0_length; + unsigned int buf1_address; + unsigned int buf1_length; +} __attribute__((packed)); +#endif /* QDSP5AUDPLAYCMD_H */ diff --git a/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h new file mode 100644 index 000000000000..c63034b8bf13 --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h @@ -0,0 +1,70 @@ +#ifndef QDSP5AUDPLAYMSG_H +#define QDSP5AUDPLAYMSG_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + Q D S P 5 A U D I O P L A Y T A S K M S G + +GENERAL DESCRIPTION + Message sent by AUDPLAY task + +REFERENCES + None + + +Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaymsg.h#3 $ + +===========================================================================*/ +#define AUDPLAY_MSG_DEC_NEEDS_DATA 0x0001 +#define AUDPLAY_MSG_DEC_NEEDS_DATA_MSG_LEN \ + sizeof(audplay_msg_dec_needs_data) + +typedef struct{ + /* reserved*/ + unsigned int dec_id; + + /* The read pointer offset of external memory until which the + * bitstream has been DMAed in. */ + unsigned int adecDataReadPtrOffset; + + /* The buffer size of external memory. */ + unsigned int adecDataBufSize; + + unsigned int bitstream_free_len; + unsigned int bitstream_write_ptr; + unsigned int bitstarem_buf_start; + unsigned int bitstream_buf_len; +} __attribute__((packed)) audplay_msg_dec_needs_data; + +#define AUDPLAY_MSG_BUFFER_UPDATE 0x0004 +#define AUDPLAY_MSG_BUFFER_UPDATE_LEN \ + sizeof(struct audplay_msg_buffer_update) + +struct audplay_msg_buffer_update { + unsigned int buffer_write_count; + unsigned int num_of_buffer; + unsigned int buf0_address; + unsigned int buf0_length; + unsigned int buf1_address; + unsigned int buf1_length; +} __attribute__((packed)); +#endif /* QDSP5AUDPLAYMSG_H */ diff --git a/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h new file mode 100644 index 000000000000..8bee9c62980b --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h @@ -0,0 +1,914 @@ +#ifndef QDSP5AUDPPCMDI_H +#define QDSP5AUDPPCMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + A U D I O P O S T P R O C E S S I N G I N T E R N A L C O M M A N D S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by AUDPP Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppcmdi.h#2 $ + +===========================================================================*/ + +/* + * ARM to AUDPPTASK Commands + * + * ARM uses three command queues to communicate with AUDPPTASK + * 1)uPAudPPCmd1Queue : Used for more frequent and shorter length commands + * Location : MEMA + * Buffer Size : 6 words + * No of buffers in a queue : 20 for gaming audio and 5 for other images + * 2)uPAudPPCmd2Queue : Used for commands which are not much lengthier + * Location : MEMA + * Buffer Size : 23 + * No of buffers in a queue : 2 + * 3)uPAudOOCmd3Queue : Used for lengthier and more frequent commands + * Location : MEMA + * Buffer Size : 145 + * No of buffers in a queue : 3 + */ + +/* + * Commands Related to uPAudPPCmd1Queue + */ + +/* + * Command Structure to enable or disable the active decoders + */ + +#define AUDPP_CMD_CFG_DEC_TYPE 0x0001 +#define AUDPP_CMD_CFG_DEC_TYPE_LEN sizeof(audpp_cmd_cfg_dec_type) + +/* Enable the decoder */ +#define AUDPP_CMD_DEC_TYPE_M 0x000F + +#define AUDPP_CMD_ENA_DEC_V 0x4000 +#define AUDPP_CMD_DIS_DEC_V 0x0000 +#define AUDPP_CMD_DEC_STATE_M 0x4000 + +#define AUDPP_CMD_UPDATDE_CFG_DEC 0x8000 +#define AUDPP_CMD_DONT_UPDATE_CFG_DEC 0x0000 + + +/* Type specification of cmd_cfg_dec */ + +typedef struct { + unsigned short cmd_id; + unsigned short dec0_cfg; + unsigned short dec1_cfg; + unsigned short dec2_cfg; + unsigned short dec3_cfg; + unsigned short dec4_cfg; +} __attribute__((packed)) audpp_cmd_cfg_dec_type; + +/* + * Command Structure to Pause , Resume and flushes the selected audio decoders + */ + +#define AUDPP_CMD_DEC_CTRL 0x0002 +#define AUDPP_CMD_DEC_CTRL_LEN sizeof(audpp_cmd_dec_ctrl) + +/* Decoder control commands for pause, resume and flush */ +#define AUDPP_CMD_FLUSH_V 0x2000 + +#define AUDPP_CMD_PAUSE_V 0x4000 +#define AUDPP_CMD_RESUME_V 0x0000 + +#define AUDPP_CMD_UPDATE_V 0x8000 +#define AUDPP_CMD_IGNORE_V 0x0000 + + +/* Type Spec for decoder control command*/ + +typedef struct { + unsigned short cmd_id; + unsigned short dec0_ctrl; + unsigned short dec1_ctrl; + unsigned short dec2_ctrl; + unsigned short dec3_ctrl; + unsigned short dec4_ctrl; +} __attribute__((packed)) audpp_cmd_dec_ctrl; + +/* + * Command Structure to Configure the AVSync FeedBack Mechanism + */ + +#define AUDPP_CMD_AVSYNC 0x0003 +#define AUDPP_CMD_AVSYNC_LEN sizeof(audpp_cmd_avsync) + +typedef struct { + unsigned short cmd_id; + unsigned short object_number; + unsigned short interrupt_interval_lsw; + unsigned short interrupt_interval_msw; +} __attribute__((packed)) audpp_cmd_avsync; + +/* + * Command Structure to enable or disable(sleep) the AUDPPTASK + */ + +#define AUDPP_CMD_CFG 0x0004 +#define AUDPP_CMD_CFG_LEN sizeof(audpp_cmd_cfg) + +#define AUDPP_CMD_CFG_SLEEP 0x0000 +#define AUDPP_CMD_CFG_ENABLE 0xFFFF + +typedef struct { + unsigned short cmd_id; + unsigned short cfg; +} __attribute__((packed)) audpp_cmd_cfg; + +/* + * Command Structure to Inject or drop the specified no of samples + */ + +#define AUDPP_CMD_ADJUST_SAMP 0x0005 +#define AUDPP_CMD_ADJUST_SAMP_LEN sizeof(audpp_cmd_adjust_samp) + +#define AUDPP_CMD_SAMP_DROP -1 +#define AUDPP_CMD_SAMP_INSERT 0x0001 + +#define AUDPP_CMD_NUM_SAMPLES 0x0001 + +typedef struct { + unsigned short cmd_id; + unsigned short object_no; + signed short sample_insert_or_drop; + unsigned short num_samples; +} __attribute__((packed)) audpp_cmd_adjust_samp; + +/* + * Command Structure to Configure AVSync Feedback Mechanism + */ + +#define AUDPP_CMD_AVSYNC_CMD_2 0x0006 +#define AUDPP_CMD_AVSYNC_CMD_2_LEN sizeof(audpp_cmd_avsync_cmd_2) + +typedef struct { + unsigned short cmd_id; + unsigned short object_number; + unsigned short interrupt_interval_lsw; + unsigned short interrupt_interval_msw; + unsigned short sample_counter_dlsw; + unsigned short sample_counter_dmsw; + unsigned short sample_counter_msw; + unsigned short byte_counter_dlsw; + unsigned short byte_counter_dmsw; + unsigned short byte_counter_msw; +} __attribute__((packed)) audpp_cmd_avsync_cmd_2; + +/* + * Command Structure to Configure AVSync Feedback Mechanism + */ + +#define AUDPP_CMD_AVSYNC_CMD_3 0x0007 +#define AUDPP_CMD_AVSYNC_CMD_3_LEN sizeof(audpp_cmd_avsync_cmd_3) + +typedef struct { + unsigned short cmd_id; + unsigned short object_number; + unsigned short interrupt_interval_lsw; + unsigned short interrupt_interval_msw; + unsigned short sample_counter_dlsw; + unsigned short sample_counter_dmsw; + unsigned short sample_counter_msw; + unsigned short byte_counter_dlsw; + unsigned short byte_counter_dmsw; + unsigned short byte_counter_msw; +} __attribute__((packed)) audpp_cmd_avsync_cmd_3; + +#define AUDPP_CMD_ROUTING_MODE 0x0008 +#define AUDPP_CMD_ROUTING_MODE_LEN \ +sizeof(struct audpp_cmd_routing_mode) + +struct audpp_cmd_routing_mode { + unsigned short cmd_id; + unsigned short object_number; + unsigned short routing_mode; +} __attribute__((packed)); + +/* + * Commands Related to uPAudPPCmd2Queue + */ + +/* + * Command Structure to configure Per decoder Parameters (Common) + */ + +#define AUDPP_CMD_CFG_ADEC_PARAMS 0x0000 +#define AUDPP_CMD_CFG_ADEC_PARAMS_COMMON_LEN \ + sizeof(audpp_cmd_cfg_adec_params_common) + +#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_FCM 0x4000 +#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_FCM 0x0000 + +#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_DCM 0x8000 +#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_DCM 0x0000 + +/* Sampling frequency*/ +#define AUDPP_CMD_SAMP_RATE_96000 0x0000 +#define AUDPP_CMD_SAMP_RATE_88200 0x0001 +#define AUDPP_CMD_SAMP_RATE_64000 0x0002 +#define AUDPP_CMD_SAMP_RATE_48000 0x0003 +#define AUDPP_CMD_SAMP_RATE_44100 0x0004 +#define AUDPP_CMD_SAMP_RATE_32000 0x0005 +#define AUDPP_CMD_SAMP_RATE_24000 0x0006 +#define AUDPP_CMD_SAMP_RATE_22050 0x0007 +#define AUDPP_CMD_SAMP_RATE_16000 0x0008 +#define AUDPP_CMD_SAMP_RATE_12000 0x0009 +#define AUDPP_CMD_SAMP_RATE_11025 0x000A +#define AUDPP_CMD_SAMP_RATE_8000 0x000B + + +/* + * Type specification of cmd_adec_cfg sent to all decoder + */ + +typedef struct { + unsigned short cmd_id; + unsigned short length; + unsigned short dec_id; + unsigned short status_msg_flag; + unsigned short decoder_frame_counter_msg_period; + unsigned short input_sampling_frequency; +} __attribute__((packed)) audpp_cmd_cfg_adec_params_common; + +/* + * Command Structure to configure Per decoder Parameters (Wav) + */ + +#define AUDPP_CMD_CFG_ADEC_PARAMS_WAV_LEN \ + sizeof(audpp_cmd_cfg_adec_params_wav) + + +#define AUDPP_CMD_WAV_STEREO_CFG_MONO 0x0001 +#define AUDPP_CMD_WAV_STEREO_CFG_STEREO 0x0002 + +#define AUDPP_CMD_WAV_PCM_WIDTH_8 0x0000 +#define AUDPP_CMD_WAV_PCM_WIDTH_16 0x0001 +#define AUDPP_CMD_WAV_PCM_WIDTH_32 0x0002 + +typedef struct { + audpp_cmd_cfg_adec_params_common common; + unsigned short stereo_cfg; + unsigned short pcm_width; + unsigned short sign; +} __attribute__((packed)) audpp_cmd_cfg_adec_params_wav; + +/* + * Command Structure to configure Per decoder Parameters (ADPCM) + */ + +#define AUDPP_CMD_CFG_ADEC_PARAMS_ADPCM_LEN \ + sizeof(audpp_cmd_cfg_adec_params_adpcm) + + +#define AUDPP_CMD_ADPCM_STEREO_CFG_MONO 0x0001 +#define AUDPP_CMD_ADPCM_STEREO_CFG_STEREO 0x0002 + +typedef struct { + audpp_cmd_cfg_adec_params_common common; + unsigned short stereo_cfg; + unsigned short block_size; +} __attribute__((packed)) audpp_cmd_cfg_adec_params_adpcm; + +/* + * Command Structure to configure Per decoder Parameters (MP3) + */ + +#define AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN \ + sizeof(audpp_cmd_cfg_adec_params_mp3) + +typedef struct { + audpp_cmd_cfg_adec_params_common common; +} __attribute__((packed)) audpp_cmd_cfg_adec_params_mp3; + + +/* + * Command Structure to configure Per decoder Parameters (AAC) + */ + +#define AUDPP_CMD_CFG_ADEC_PARAMS_AAC_LEN \ + sizeof(audpp_cmd_cfg_adec_params_aac) + + +#define AUDPP_CMD_AAC_FORMAT_ADTS -1 +#define AUDPP_CMD_AAC_FORMAT_RAW 0x0000 +#define AUDPP_CMD_AAC_FORMAT_PSUEDO_RAW 0x0001 +#define AUDPP_CMD_AAC_FORMAT_LOAS 0x0002 + +#define AUDPP_CMD_AAC_AUDIO_OBJECT_LC 0x0002 +#define AUDPP_CMD_AAC_AUDIO_OBJECT_LTP 0x0004 +#define AUDPP_CMD_AAC_AUDIO_OBJECT_ERLC 0x0011 + +#define AUDPP_CMD_AAC_SBR_ON_FLAG_ON 0x0001 +#define AUDPP_CMD_AAC_SBR_ON_FLAG_OFF 0x0000 + +#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_ON 0x0001 +#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_OFF 0x0000 + +typedef struct { + audpp_cmd_cfg_adec_params_common common; + signed short format; + unsigned short audio_object; + unsigned short ep_config; + unsigned short aac_section_data_resilience_flag; + unsigned short aac_scalefactor_data_resilience_flag; + unsigned short aac_spectral_data_resilience_flag; + unsigned short sbr_on_flag; + unsigned short sbr_ps_on_flag; + unsigned short dual_mono_mode; + unsigned short channel_configuration; +} __attribute__((packed)) audpp_cmd_cfg_adec_params_aac; + +/* + * Command Structure to configure Per decoder Parameters (V13K) + */ + +#define AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN \ + sizeof(struct audpp_cmd_cfg_adec_params_v13k) + + +#define AUDPP_CMD_STEREO_CFG_MONO 0x0001 +#define AUDPP_CMD_STEREO_CFG_STEREO 0x0002 + +struct audpp_cmd_cfg_adec_params_v13k { + audpp_cmd_cfg_adec_params_common common; + unsigned short stereo_cfg; +} __attribute__((packed)); + +#define AUDPP_CMD_CFG_ADEC_PARAMS_EVRC_LEN \ + sizeof(struct audpp_cmd_cfg_adec_params_evrc) + +struct audpp_cmd_cfg_adec_params_evrc { + audpp_cmd_cfg_adec_params_common common; + unsigned short stereo_cfg; +} __attribute__ ((packed)); + +/* + * Command Structure to configure the HOST PCM interface + */ + +#define AUDPP_CMD_PCM_INTF 0x0001 +#define AUDPP_CMD_PCM_INTF_2 0x0002 +#define AUDPP_CMD_PCM_INTF_LEN sizeof(audpp_cmd_pcm_intf) + +#define AUDPP_CMD_PCM_INTF_MONO_V 0x0001 +#define AUDPP_CMD_PCM_INTF_STEREO_V 0x0002 + +/* These two values differentiate the two types of commands that could be issued + * Interface configuration command and Buffer update command */ + +#define AUDPP_CMD_PCM_INTF_CONFIG_CMD_V 0x0000 +#define AUDPP_CMD_PCM_INTF_BUFFER_CMD_V -1 + +#define AUDPP_CMD_PCM_INTF_RX_ENA_M 0x000F +#define AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V 0x0008 +#define AUDPP_CMD_PCM_INTF_RX_ENA_DSPTOARM_V 0x0004 + +/* These flags control the enabling and disabling of the interface together + * with host interface bit mask. */ + +#define AUDPP_CMD_PCM_INTF_ENA_V -1 +#define AUDPP_CMD_PCM_INTF_DIS_V 0x0000 + + +#define AUDPP_CMD_PCM_INTF_FULL_DUPLEX 0x0 +#define AUDPP_CMD_PCM_INTF_HALF_DUPLEX_TODSP 0x1 + + +#define AUDPP_CMD_PCM_INTF_OBJECT_NUM 0x5 +#define AUDPP_CMD_PCM_INTF_COMMON_OBJECT_NUM 0x6 + + +typedef struct { + unsigned short cmd_id; + unsigned short object_num; + signed short config; + unsigned short intf_type; + + /* DSP -> ARM Configuration */ + unsigned short read_buf1LSW; + unsigned short read_buf1MSW; + unsigned short read_buf1_len; + + unsigned short read_buf2LSW; + unsigned short read_buf2MSW; + unsigned short read_buf2_len; + /* 0:HOST_PCM_INTF disable + ** 0xFFFF: HOST_PCM_INTF enable + */ + signed short dsp_to_arm_flag; + unsigned short partition_number; + + /* ARM -> DSP Configuration */ + unsigned short write_buf1LSW; + unsigned short write_buf1MSW; + unsigned short write_buf1_len; + + unsigned short write_buf2LSW; + unsigned short write_buf2MSW; + unsigned short write_buf2_len; + + /* 0:HOST_PCM_INTF disable + ** 0xFFFF: HOST_PCM_INTF enable + */ + signed short arm_to_rx_flag; + unsigned short weight_decoder_to_rx; + unsigned short weight_arm_to_rx; + + unsigned short partition_number_arm_to_dsp; + unsigned short sample_rate; + unsigned short channel_mode; +} __attribute__((packed)) audpp_cmd_pcm_intf; + +/* + ** BUFFER UPDATE COMMAND + */ +#define AUDPP_CMD_PCM_INTF_SEND_BUF_PARAMS_LEN \ + sizeof(audpp_cmd_pcm_intf_send_buffer) + +typedef struct { + unsigned short cmd_id; + unsigned short host_pcm_object; + /* set config = 0xFFFF for configuration*/ + signed short config; + unsigned short intf_type; + unsigned short dsp_to_arm_buf_id; + unsigned short arm_to_dsp_buf_id; + unsigned short arm_to_dsp_buf_len; +} __attribute__((packed)) audpp_cmd_pcm_intf_send_buffer; + + +/* + * Commands Related to uPAudPPCmd3Queue + */ + +/* + * Command Structure to configure post processing params (Commmon) + */ + +#define AUDPP_CMD_CFG_OBJECT_PARAMS 0x0000 +#define AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN \ + sizeof(audpp_cmd_cfg_object_params_common) + +#define AUDPP_CMD_OBJ0_UPDATE 0x8000 +#define AUDPP_CMD_OBJ0_DONT_UPDATE 0x0000 + +#define AUDPP_CMD_OBJ1_UPDATE 0x8000 +#define AUDPP_CMD_OBJ1_DONT_UPDATE 0x0000 + +#define AUDPP_CMD_OBJ2_UPDATE 0x8000 +#define AUDPP_CMD_OBJ2_DONT_UPDATE 0x0000 + +#define AUDPP_CMD_OBJ3_UPDATE 0x8000 +#define AUDPP_CMD_OBJ3_DONT_UPDATE 0x0000 + +#define AUDPP_CMD_OBJ4_UPDATE 0x8000 +#define AUDPP_CMD_OBJ4_DONT_UPDATE 0x0000 + +#define AUDPP_CMD_HPCM_UPDATE 0x8000 +#define AUDPP_CMD_HPCM_DONT_UPDATE 0x0000 + +#define AUDPP_CMD_COMMON_CFG_UPDATE 0x8000 +#define AUDPP_CMD_COMMON_CFG_DONT_UPDATE 0x0000 + +typedef struct { + unsigned short cmd_id; + unsigned short obj0_cfg; + unsigned short obj1_cfg; + unsigned short obj2_cfg; + unsigned short obj3_cfg; + unsigned short obj4_cfg; + unsigned short host_pcm_obj_cfg; + unsigned short comman_cfg; + unsigned short command_type; +} __attribute__((packed)) audpp_cmd_cfg_object_params_common; + +/* + * Command Structure to configure post processing params (Volume) + */ + +#define AUDPP_CMD_CFG_OBJECT_PARAMS_VOLUME_LEN \ + sizeof(audpp_cmd_cfg_object_params_volume) + +typedef struct { + audpp_cmd_cfg_object_params_common common; + unsigned short volume; + unsigned short pan; +} __attribute__((packed)) audpp_cmd_cfg_object_params_volume; + +/* + * Command Structure to configure post processing params (PCM Filter) --DOUBT + */ + +typedef struct { + unsigned short numerator_b0_filter_lsw; + unsigned short numerator_b0_filter_msw; + unsigned short numerator_b1_filter_lsw; + unsigned short numerator_b1_filter_msw; + unsigned short numerator_b2_filter_lsw; + unsigned short numerator_b2_filter_msw; +} __attribute__((packed)) numerator; + +typedef struct { + unsigned short denominator_a0_filter_lsw; + unsigned short denominator_a0_filter_msw; + unsigned short denominator_a1_filter_lsw; + unsigned short denominator_a1_filter_msw; +} __attribute__((packed)) denominator; + +typedef struct { + unsigned short shift_factor_0; +} __attribute__((packed)) shift_factor; + +typedef struct { + unsigned short pan_filter_0; +} __attribute__((packed)) pan; + +typedef struct { + numerator numerator_filter; + denominator denominator_filter; + shift_factor shift_factor_filter; + pan pan_filter; +} __attribute__((packed)) filter_1; + +typedef struct { + numerator numerator_filter[2]; + denominator denominator_filter[2]; + shift_factor shift_factor_filter[2]; + pan pan_filter[2]; +} __attribute__((packed)) filter_2; + +typedef struct { + numerator numerator_filter[3]; + denominator denominator_filter[3]; + shift_factor shift_factor_filter[3]; + pan pan_filter[3]; +} __attribute__((packed)) filter_3; + +typedef struct { + numerator numerator_filter[4]; + denominator denominator_filter[4]; + shift_factor shift_factor_filter[4]; + pan pan_filter[4]; +} __attribute__((packed)) filter_4; + +#define AUDPP_CMD_CFG_OBJECT_PARAMS_PCM_LEN \ + sizeof(audpp_cmd_cfg_object_params_pcm) + + +typedef struct { + audpp_cmd_cfg_object_params_common common; + unsigned short active_flag; + unsigned short num_bands; + union { + filter_1 filter_1_params; + filter_2 filter_2_params; + filter_3 filter_3_params; + filter_4 filter_4_params; + } __attribute__((packed)) params_filter; +} __attribute__((packed)) audpp_cmd_cfg_object_params_pcm; + + +/* + * Command Structure to configure post processing parameters (equalizer) + */ + +#define AUDPP_CMD_CFG_OBJECT_PARAMS_EQALIZER_LEN \ + sizeof(audpp_cmd_cfg_object_params_eqalizer) + +typedef struct { + unsigned short numerator_coeff_0_lsw; + unsigned short numerator_coeff_0_msw; + unsigned short numerator_coeff_1_lsw; + unsigned short numerator_coeff_1_msw; + unsigned short numerator_coeff_2_lsw; + unsigned short numerator_coeff_2_msw; +} __attribute__((packed)) eq_numerator; + +typedef struct { + unsigned short denominator_coeff_0_lsw; + unsigned short denominator_coeff_0_msw; + unsigned short denominator_coeff_1_lsw; + unsigned short denominator_coeff_1_msw; +} __attribute__((packed)) eq_denominator; + +typedef struct { + unsigned short shift_factor; +} __attribute__((packed)) eq_shiftfactor; + +typedef struct { + eq_numerator numerator; + eq_denominator denominator; + eq_shiftfactor shiftfactor; +} __attribute__((packed)) eq_coeff_1; + +typedef struct { + eq_numerator numerator[2]; + eq_denominator denominator[2]; + eq_shiftfactor shiftfactor[2]; +} __attribute__((packed)) eq_coeff_2; + +typedef struct { + eq_numerator numerator[3]; + eq_denominator denominator[3]; + eq_shiftfactor shiftfactor[3]; +} __attribute__((packed)) eq_coeff_3; + +typedef struct { + eq_numerator numerator[4]; + eq_denominator denominator[4]; + eq_shiftfactor shiftfactor[4]; +} __attribute__((packed)) eq_coeff_4; + +typedef struct { + eq_numerator numerator[5]; + eq_denominator denominator[5]; + eq_shiftfactor shiftfactor[5]; +} __attribute__((packed)) eq_coeff_5; + +typedef struct { + eq_numerator numerator[6]; + eq_denominator denominator[6]; + eq_shiftfactor shiftfactor[6]; +} __attribute__((packed)) eq_coeff_6; + +typedef struct { + eq_numerator numerator[7]; + eq_denominator denominator[7]; + eq_shiftfactor shiftfactor[7]; +} __attribute__((packed)) eq_coeff_7; + +typedef struct { + eq_numerator numerator[8]; + eq_denominator denominator[8]; + eq_shiftfactor shiftfactor[8]; +} __attribute__((packed)) eq_coeff_8; + +typedef struct { + eq_numerator numerator[9]; + eq_denominator denominator[9]; + eq_shiftfactor shiftfactor[9]; +} __attribute__((packed)) eq_coeff_9; + +typedef struct { + eq_numerator numerator[10]; + eq_denominator denominator[10]; + eq_shiftfactor shiftfactor[10]; +} __attribute__((packed)) eq_coeff_10; + +typedef struct { + eq_numerator numerator[11]; + eq_denominator denominator[11]; + eq_shiftfactor shiftfactor[11]; +} __attribute__((packed)) eq_coeff_11; + +typedef struct { + eq_numerator numerator[12]; + eq_denominator denominator[12]; + eq_shiftfactor shiftfactor[12]; +} __attribute__((packed)) eq_coeff_12; + + +typedef struct { + audpp_cmd_cfg_object_params_common common; + unsigned short eq_flag; + unsigned short num_bands; + union { + eq_coeff_1 eq_coeffs_1; + eq_coeff_2 eq_coeffs_2; + eq_coeff_3 eq_coeffs_3; + eq_coeff_4 eq_coeffs_4; + eq_coeff_5 eq_coeffs_5; + eq_coeff_6 eq_coeffs_6; + eq_coeff_7 eq_coeffs_7; + eq_coeff_8 eq_coeffs_8; + eq_coeff_9 eq_coeffs_9; + eq_coeff_10 eq_coeffs_10; + eq_coeff_11 eq_coeffs_11; + eq_coeff_12 eq_coeffs_12; + } __attribute__((packed)) eq_coeff; +} __attribute__((packed)) audpp_cmd_cfg_object_params_eqalizer; + + +/* + * Command Structure to configure post processing parameters (ADRC) + */ + +#define AUDPP_CMD_CFG_OBJECT_PARAMS_ADRC_LEN \ + sizeof(audpp_cmd_cfg_object_params_adrc) + + +#define AUDPP_CMD_ADRC_FLAG_DIS 0x0000 +#define AUDPP_CMD_ADRC_FLAG_ENA -1 + +typedef struct { + audpp_cmd_cfg_object_params_common common; + signed short adrc_flag; + unsigned short compression_th; + unsigned short compression_slope; + unsigned short rms_time; + unsigned short attack_const_lsw; + unsigned short attack_const_msw; + unsigned short release_const_lsw; + unsigned short release_const_msw; + unsigned short adrc_system_delay; +} __attribute__((packed)) audpp_cmd_cfg_object_params_adrc; + +/* + * Command Structure to configure post processing parameters(Spectrum Analizer) + */ + +#define AUDPP_CMD_CFG_OBJECT_PARAMS_SPECTRAM_LEN \ + sizeof(audpp_cmd_cfg_object_params_spectram) + + +typedef struct { + audpp_cmd_cfg_object_params_common common; + unsigned short sample_interval; + unsigned short num_coeff; +} __attribute__((packed)) audpp_cmd_cfg_object_params_spectram; + +/* + * Command Structure to configure post processing parameters (QConcert) + */ + +#define AUDPP_CMD_CFG_OBJECT_PARAMS_QCONCERT_LEN \ + sizeof(audpp_cmd_cfg_object_params_qconcert) + + +#define AUDPP_CMD_QCON_ENA_FLAG_ENA -1 +#define AUDPP_CMD_QCON_ENA_FLAG_DIS 0x0000 + +#define AUDPP_CMD_QCON_OP_MODE_HEADPHONE -1 +#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_FRONT 0x0000 +#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_SIDE 0x0001 +#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_DESKTOP 0x0002 + +#define AUDPP_CMD_QCON_GAIN_UNIT 0x7FFF +#define AUDPP_CMD_QCON_GAIN_SIX_DB 0x4027 + + +#define AUDPP_CMD_QCON_EXPANSION_MAX 0x7FFF + + +typedef struct { + audpp_cmd_cfg_object_params_common common; + signed short enable_flag; + signed short output_mode; + signed short gain; + signed short expansion; + signed short delay; + unsigned short stages_per_mode; +} __attribute__((packed)) audpp_cmd_cfg_object_params_qconcert; + +/* + * Command Structure to configure post processing parameters (Side Chain) + */ + +#define AUDPP_CMD_CFG_OBJECT_PARAMS_SIDECHAIN_LEN \ + sizeof(audpp_cmd_cfg_object_params_sidechain) + + +#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_DIS 0x0000 +#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_ENA -1 + +typedef struct { + audpp_cmd_cfg_object_params_common common; + signed short active_flag; + unsigned short num_bands; + union { + filter_1 filter_1_params; + filter_2 filter_2_params; + filter_3 filter_3_params; + filter_4 filter_4_params; + } __attribute__((packed)) params_filter; +} __attribute__((packed)) audpp_cmd_cfg_object_params_sidechain; + + +/* + * Command Structure to configure post processing parameters (QAFX) + */ + +#define AUDPP_CMD_CFG_OBJECT_PARAMS_QAFX_LEN \ + sizeof(audpp_cmd_cfg_object_params_qafx) + +#define AUDPP_CMD_QAFX_ENA_DISA 0x0000 +#define AUDPP_CMD_QAFX_ENA_ENA_CFG -1 +#define AUDPP_CMD_QAFX_ENA_DIS_CFG 0x0001 + +#define AUDPP_CMD_QAFX_CMD_TYPE_ENV 0x0100 +#define AUDPP_CMD_QAFX_CMD_TYPE_OBJ 0x0010 +#define AUDPP_CMD_QAFX_CMD_TYPE_QUERY 0x1000 + +#define AUDPP_CMD_QAFX_CMDS_ENV_OP_MODE 0x0100 +#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_POS 0x0101 +#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_ORI 0x0102 +#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_VEL 0X0103 +#define AUDPP_CMD_QAFX_CMDS_ENV_ENV_RES 0x0107 + +#define AUDPP_CMD_QAFX_CMDS_OBJ_SAMP_FREQ 0x0010 +#define AUDPP_CMD_QAFX_CMDS_OBJ_VOL 0x0011 +#define AUDPP_CMD_QAFX_CMDS_OBJ_DIST 0x0012 +#define AUDPP_CMD_QAFX_CMDS_OBJ_POS 0x0013 +#define AUDPP_CMD_QAFX_CMDS_OBJ_VEL 0x0014 + + +typedef struct { + audpp_cmd_cfg_object_params_common common; + signed short enable; + unsigned short command_type; + unsigned short num_commands; + unsigned short commands; +} __attribute__((packed)) audpp_cmd_cfg_object_params_qafx; + +/* + * Command Structure to enable , disable or configure the reverberation effect + * (Common) + */ + +#define AUDPP_CMD_REVERB_CONFIG 0x0001 +#define AUDPP_CMD_REVERB_CONFIG_COMMON_LEN \ + sizeof(audpp_cmd_reverb_config_common) + +#define AUDPP_CMD_ENA_ENA 0xFFFF +#define AUDPP_CMD_ENA_DIS 0x0000 +#define AUDPP_CMD_ENA_CFG 0x0001 + +#define AUDPP_CMD_CMD_TYPE_ENV 0x0104 +#define AUDPP_CMD_CMD_TYPE_OBJ 0x0015 +#define AUDPP_CMD_CMD_TYPE_QUERY 0x1000 + + +typedef struct { + unsigned short cmd_id; + unsigned short enable; + unsigned short cmd_type; +} __attribute__((packed)) audpp_cmd_reverb_config_common; + +/* + * Command Structure to enable , disable or configure the reverberation effect + * (ENV-0x0104) + */ + +#define AUDPP_CMD_REVERB_CONFIG_ENV_104_LEN \ + sizeof(audpp_cmd_reverb_config_env_104) + +typedef struct { + audpp_cmd_reverb_config_common common; + unsigned short env_gain; + unsigned short decay_msw; + unsigned short decay_lsw; + unsigned short decay_timeratio_msw; + unsigned short decay_timeratio_lsw; + unsigned short delay_time; + unsigned short reverb_gain; + unsigned short reverb_delay; +} __attribute__((packed)) audpp_cmd_reverb_config_env_104; + +/* + * Command Structure to enable , disable or configure the reverberation effect + * (ENV-0x0015) + */ + +#define AUDPP_CMD_REVERB_CONFIG_ENV_15_LEN \ + sizeof(audpp_cmd_reverb_config_env_15) + +typedef struct { + audpp_cmd_reverb_config_common common; + unsigned short object_num; + unsigned short absolute_gain; +} __attribute__((packed)) audpp_cmd_reverb_config_env_15; + + +#endif /* QDSP5AUDPPCMDI_H */ + diff --git a/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h new file mode 100644 index 000000000000..44fea224001a --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h @@ -0,0 +1,318 @@ +#ifndef QDSP5AUDPPMSG_H +#define QDSP5AUDPPMSG_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + Q D S P 5 A U D I O P O S T P R O C E S S I N G M S G + +GENERAL DESCRIPTION + Messages sent by AUDPPTASK to ARM + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + + $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppmsg.h#4 $ + +===========================================================================*/ + +/* + * AUDPPTASK uses audPPuPRlist to send messages to the ARM + * Location : MEMA + * Buffer Size : 45 + * No of Buffers in a queue : 5 for gaming audio and 1 for other images + */ + +/* + * MSG to Informs the ARM os Success/Failure of bringing up the decoder + */ + +#define AUDPP_MSG_STATUS_MSG 0x0001 +#define AUDPP_MSG_STATUS_MSG_LEN \ + sizeof(audpp_msg_status_msg) + +#define AUDPP_MSG_STATUS_SLEEP 0x0000 +#define AUDPP_MSG__STATUS_INIT 0x0001 +#define AUDPP_MSG_MSG_STATUS_CFG 0x0002 +#define AUDPP_MSG_STATUS_PLAY 0x0003 + +#define AUDPP_MSG_REASON_MIPS 0x0000 +#define AUDPP_MSG_REASON_MEM 0x0001 + +typedef struct{ + unsigned short dec_id; + unsigned short status; + unsigned short reason; +} __attribute__((packed)) audpp_msg_status_msg; + +/* + * MSG to communicate the spectrum analyzer output bands to the ARM + */ +#define AUDPP_MSG_SPA_BANDS 0x0002 +#define AUDPP_MSG_SPA_BANDS_LEN \ + sizeof(audpp_msg_spa_bands) + +typedef struct { + unsigned short current_object; + unsigned short spa_band_1; + unsigned short spa_band_2; + unsigned short spa_band_3; + unsigned short spa_band_4; + unsigned short spa_band_5; + unsigned short spa_band_6; + unsigned short spa_band_7; + unsigned short spa_band_8; + unsigned short spa_band_9; + unsigned short spa_band_10; + unsigned short spa_band_11; + unsigned short spa_band_12; + unsigned short spa_band_13; + unsigned short spa_band_14; + unsigned short spa_band_15; + unsigned short spa_band_16; + unsigned short spa_band_17; + unsigned short spa_band_18; + unsigned short spa_band_19; + unsigned short spa_band_20; + unsigned short spa_band_21; + unsigned short spa_band_22; + unsigned short spa_band_23; + unsigned short spa_band_24; + unsigned short spa_band_25; + unsigned short spa_band_26; + unsigned short spa_band_27; + unsigned short spa_band_28; + unsigned short spa_band_29; + unsigned short spa_band_30; + unsigned short spa_band_31; + unsigned short spa_band_32; +} __attribute__((packed)) audpp_msg_spa_bands; + +/* + * MSG to communicate the PCM I/O buffer status to ARM + */ +#define AUDPP_MSG_HOST_PCM_INTF_MSG 0x0003 +#define AUDPP_MSG_HOST_PCM_INTF_MSG_LEN \ + sizeof(audpp_msg_host_pcm_intf_msg) + +#define AUDPP_MSG_HOSTPCM_ID_TX_ARM 0x0000 +#define AUDPP_MSG_HOSTPCM_ID_ARM_TX 0x0001 +#define AUDPP_MSG_HOSTPCM_ID_RX_ARM 0x0002 +#define AUDPP_MSG_HOSTPCM_ID_ARM_RX 0x0003 + +#define AUDPP_MSG_SAMP_FREQ_INDX_96000 0x0000 +#define AUDPP_MSG_SAMP_FREQ_INDX_88200 0x0001 +#define AUDPP_MSG_SAMP_FREQ_INDX_64000 0x0002 +#define AUDPP_MSG_SAMP_FREQ_INDX_48000 0x0003 +#define AUDPP_MSG_SAMP_FREQ_INDX_44100 0x0004 +#define AUDPP_MSG_SAMP_FREQ_INDX_32000 0x0005 +#define AUDPP_MSG_SAMP_FREQ_INDX_24000 0x0006 +#define AUDPP_MSG_SAMP_FREQ_INDX_22050 0x0007 +#define AUDPP_MSG_SAMP_FREQ_INDX_16000 0x0008 +#define AUDPP_MSG_SAMP_FREQ_INDX_12000 0x0009 +#define AUDPP_MSG_SAMP_FREQ_INDX_11025 0x000A +#define AUDPP_MSG_SAMP_FREQ_INDX_8000 0x000B + +#define AUDPP_MSG_CHANNEL_MODE_MONO 0x0001 +#define AUDPP_MSG_CHANNEL_MODE_STEREO 0x0002 + +typedef struct{ + unsigned short obj_num; + unsigned short numbers_of_samples; + unsigned short host_pcm_id; + unsigned short buf_indx; + unsigned short samp_freq_indx; + unsigned short channel_mode; +} __attribute__((packed)) audpp_msg_host_pcm_intf_msg; + + +/* + * MSG to communicate 3D position of the source and listener , source volume + * source rolloff, source orientation + */ + +#define AUDPP_MSG_QAFX_POS 0x0004 +#define AUDPP_MSG_QAFX_POS_LEN \ + sizeof(audpp_msg_qafx_pos) + +typedef struct { + unsigned short current_object; + unsigned short x_pos_lis_msw; + unsigned short x_pos_lis_lsw; + unsigned short y_pos_lis_msw; + unsigned short y_pos_lis_lsw; + unsigned short z_pos_lis_msw; + unsigned short z_pos_lis_lsw; + unsigned short x_fwd_msw; + unsigned short x_fwd_lsw; + unsigned short y_fwd_msw; + unsigned short y_fwd_lsw; + unsigned short z_fwd_msw; + unsigned short z_fwd_lsw; + unsigned short x_up_msw; + unsigned short x_up_lsw; + unsigned short y_up_msw; + unsigned short y_up_lsw; + unsigned short z_up_msw; + unsigned short z_up_lsw; + unsigned short x_vel_lis_msw; + unsigned short x_vel_lis_lsw; + unsigned short y_vel_lis_msw; + unsigned short y_vel_lis_lsw; + unsigned short z_vel_lis_msw; + unsigned short z_vel_lis_lsw; + unsigned short threed_enable_flag; + unsigned short volume; + unsigned short x_pos_source_msw; + unsigned short x_pos_source_lsw; + unsigned short y_pos_source_msw; + unsigned short y_pos_source_lsw; + unsigned short z_pos_source_msw; + unsigned short z_pos_source_lsw; + unsigned short max_dist_0_msw; + unsigned short max_dist_0_lsw; + unsigned short min_dist_0_msw; + unsigned short min_dist_0_lsw; + unsigned short roll_off_factor; + unsigned short mute_after_max_flag; + unsigned short x_vel_source_msw; + unsigned short x_vel_source_lsw; + unsigned short y_vel_source_msw; + unsigned short y_vel_source_lsw; + unsigned short z_vel_source_msw; + unsigned short z_vel_source_lsw; +} __attribute__((packed)) audpp_msg_qafx_pos; + +/* + * MSG to provide AVSYNC feedback from DSP to ARM + */ + +#define AUDPP_MSG_AVSYNC_MSG 0x0005 +#define AUDPP_MSG_AVSYNC_MSG_LEN \ + sizeof(audpp_msg_avsync_msg) + +typedef struct { + unsigned short active_flag; + unsigned short num_samples_counter0_HSW; + unsigned short num_samples_counter0_MSW; + unsigned short num_samples_counter0_LSW; + unsigned short num_bytes_counter0_HSW; + unsigned short num_bytes_counter0_MSW; + unsigned short num_bytes_counter0_LSW; + unsigned short samp_freq_obj_0; + unsigned short samp_freq_obj_1; + unsigned short samp_freq_obj_2; + unsigned short samp_freq_obj_3; + unsigned short samp_freq_obj_4; + unsigned short samp_freq_obj_5; + unsigned short samp_freq_obj_6; + unsigned short samp_freq_obj_7; + unsigned short samp_freq_obj_8; + unsigned short samp_freq_obj_9; + unsigned short samp_freq_obj_10; + unsigned short samp_freq_obj_11; + unsigned short samp_freq_obj_12; + unsigned short samp_freq_obj_13; + unsigned short samp_freq_obj_14; + unsigned short samp_freq_obj_15; + unsigned short num_samples_counter4_HSW; + unsigned short num_samples_counter4_MSW; + unsigned short num_samples_counter4_LSW; + unsigned short num_bytes_counter4_HSW; + unsigned short num_bytes_counter4_MSW; + unsigned short num_bytes_counter4_LSW; +} __attribute__((packed)) audpp_msg_avsync_msg; + +/* + * MSG to provide PCM DMA Missed feedback from the DSP to ARM + */ + +#define AUDPP_MSG_PCMDMAMISSED 0x0006 +#define AUDPP_MSG_PCMDMAMISSED_LEN \ + sizeof(audpp_msg_pcmdmamissed); + +typedef struct{ + /* + ** Bit 0 0 = PCM DMA not missed for object 0 + ** 1 = PCM DMA missed for object0 + ** Bit 1 0 = PCM DMA not missed for object 1 + ** 1 = PCM DMA missed for object1 + ** Bit 2 0 = PCM DMA not missed for object 2 + ** 1 = PCM DMA missed for object2 + ** Bit 3 0 = PCM DMA not missed for object 3 + ** 1 = PCM DMA missed for object3 + ** Bit 4 0 = PCM DMA not missed for object 4 + ** 1 = PCM DMA missed for object4 + */ + unsigned short pcmdmamissed; +} __attribute__((packed)) audpp_msg_pcmdmamissed; + +/* + * MSG to AUDPP enable or disable feedback form DSP to ARM + */ + +#define AUDPP_MSG_CFG_MSG 0x0007 +#define AUDPP_MSG_CFG_MSG_LEN \ + sizeof(audpp_msg_cfg_msg) + +#define AUDPP_MSG_ENA_ENA 0xFFFF +#define AUDPP_MSG_ENA_DIS 0x0000 + +typedef struct{ + /* Enabled - 0xffff + ** Disabled - 0 + */ + unsigned short enabled; +} __attribute__((packed)) audpp_msg_cfg_msg; + +/* + * MSG to communicate the reverb per object volume + */ + +#define AUDPP_MSG_QREVERB_VOLUME 0x0008 +#define AUDPP_MSG_QREVERB_VOLUME_LEN \ + sizeof(audpp_msg_qreverb_volume) + + +typedef struct { + unsigned short obj_0_gain; + unsigned short obj_1_gain; + unsigned short obj_2_gain; + unsigned short obj_3_gain; + unsigned short obj_4_gain; + unsigned short hpcm_obj_volume; +} __attribute__((packed)) audpp_msg_qreverb_volume; + +#define AUDPP_MSG_ROUTING_ACK 0x0009 +#define AUDPP_MSG_ROUTING_ACK_LEN \ + sizeof(struct audpp_msg_routing_ack) + +struct audpp_msg_routing_ack { + unsigned short dec_id; + unsigned short routing_mode; +} __attribute__((packed)); + +#define AUDPP_MSG_FLUSH_ACK 0x000A + +#endif /* QDSP5AUDPPMSG_H */ diff --git a/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h new file mode 100644 index 000000000000..06d33d571583 --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h @@ -0,0 +1,256 @@ +#ifndef QDSP5AUDPREPROCCMDI_H +#define QDSP5AUDPREPROCCMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + A U D I O P R E P R O C E S S I N G I N T E R N A L C O M M A N D S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by AUDPREPROC Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreproccmdi.h#2 $ + +===========================================================================*/ + +/* + * AUDIOPREPROC COMMANDS: + * ARM uses uPAudPreProcCmdQueue to communicate with AUDPREPROCTASK + * Location : MEMB + * Buffer size : 51 + * Number of buffers in a queue : 3 + */ + +/* + * Command to configure the parameters of AGC + */ + +#define AUDPREPROC_CMD_CFG_AGC_PARAMS 0x0000 +#define AUDPREPROC_CMD_CFG_AGC_PARAMS_LEN \ + sizeof(audpreproc_cmd_cfg_agc_params) + +#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE 0x0009 +#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH 0x000A +#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE 0x000B +#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH 0x000C +#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG 0x000D +#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN 0x000E +#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG 0x000F + +#define AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA -1 +#define AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS 0x0000 + +#define AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_ADP_GAIN -1 +#define AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_STATIC_GAIN 0x0000 + +#define AUDPREPROC_CMD_PARAM_MASK_RMS_TAY 0x0004 +#define AUDPREPROC_CMD_PARAM_MASK_RELEASEK 0x0005 +#define AUDPREPROC_CMD_PARAM_MASK_DELAY 0x0006 +#define AUDPREPROC_CMD_PARAM_MASK_ATTACKK 0x0007 +#define AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW 0x0008 +#define AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST 0x0009 +#define AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK 0x000A +#define AUDPREPROC_CMD_PARAM_MASK_AIG_MIN 0x000B +#define AUDPREPROC_CMD_PARAM_MASK_AIG_MAX 0x000C +#define AUDPREPROC_CMD_PARAM_MASK_LEAK_UP 0x000D +#define AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN 0x000E +#define AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK 0x000F + +typedef struct { + unsigned short cmd_id; + unsigned short tx_agc_param_mask; + unsigned short tx_agc_enable_flag; + unsigned short static_gain; + signed short adaptive_gain_flag; + unsigned short expander_th; + unsigned short expander_slope; + unsigned short compressor_th; + unsigned short compressor_slope; + unsigned short param_mask; + unsigned short aig_attackk; + unsigned short aig_leak_down; + unsigned short aig_leak_up; + unsigned short aig_max; + unsigned short aig_min; + unsigned short aig_releasek; + unsigned short aig_leakrate_fast; + unsigned short aig_leakrate_slow; + unsigned short attackk_msw; + unsigned short attackk_lsw; + unsigned short delay; + unsigned short releasek_msw; + unsigned short releasek_lsw; + unsigned short rms_tav; +} __attribute__((packed)) audpreproc_cmd_cfg_agc_params; + + +/* + * Command to configure the params of Advanved AGC + */ + +#define AUDPREPROC_CMD_CFG_AGC_PARAMS_2 0x0001 +#define AUDPREPROC_CMD_CFG_AGC_PARAMS_2_LEN \ + sizeof(audpreproc_cmd_cfg_agc_params_2) + +#define AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_ENA -1; +#define AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_DIS 0x0000; + +typedef struct { + unsigned short cmd_id; + unsigned short agc_param_mask; + signed short tx_agc_enable_flag; + unsigned short comp_static_gain; + unsigned short exp_th; + unsigned short exp_slope; + unsigned short comp_th; + unsigned short comp_slope; + unsigned short comp_rms_tav; + unsigned short comp_samp_mask; + unsigned short comp_attackk_msw; + unsigned short comp_attackk_lsw; + unsigned short comp_releasek_msw; + unsigned short comp_releasek_lsw; + unsigned short comp_delay; + unsigned short comp_makeup_gain; +} __attribute__((packed)) audpreproc_cmd_cfg_agc_params_2; + +/* + * Command to configure params for ns + */ + +#define AUDPREPROC_CMD_CFG_NS_PARAMS 0x0002 +#define AUDPREPROC_CMD_CFG_NS_PARAMS_LEN \ + sizeof(audpreproc_cmd_cfg_ns_params) + +#define AUDPREPROC_CMD_EC_MODE_NEW_NLMS_ENA 0x0001 +#define AUDPREPROC_CMD_EC_MODE_NEW_NLMS_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_DES_ENA 0x0002 +#define AUDPREPROC_CMD_EC_MODE_NEW_DES_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA 0x0004 +#define AUDPREPROC_CMD_EC_MODE_NEW_NS_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_CNI_ENA 0x0008 +#define AUDPREPROC_CMD_EC_MODE_NEW_CNI_DIS 0x0000 + +#define AUDPREPROC_CMD_EC_MODE_NEW_NLES_ENA 0x0010 +#define AUDPREPROC_CMD_EC_MODE_NEW_NLES_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA 0x0020 +#define AUDPREPROC_CMD_EC_MODE_NEW_HB_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA 0x0040 +#define AUDPREPROC_CMD_EC_MODE_NEW_VA_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_PCD_ENA 0x0080 +#define AUDPREPROC_CMD_EC_MODE_NEW_PCD_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_FEHI_ENA 0x0100 +#define AUDPREPROC_CMD_EC_MODE_NEW_FEHI_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_NEHI_ENA 0x0200 +#define AUDPREPROC_CMD_EC_MODE_NEW_NEHI_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_NLPP_ENA 0x0400 +#define AUDPREPROC_CMD_EC_MODE_NEW_NLPP_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_FNE_ENA 0x0800 +#define AUDPREPROC_CMD_EC_MODE_NEW_FNE_DIS 0x0000 +#define AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_ENA 0x1000 +#define AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_DIS 0x0000 + +typedef struct { + unsigned short cmd_id; + unsigned short ec_mode_new; + unsigned short dens_gamma_n; + unsigned short dens_nfe_block_size; + unsigned short dens_limit_ns; + unsigned short dens_limit_ns_d; + unsigned short wb_gamma_e; + unsigned short wb_gamma_n; +} __attribute__((packed)) audpreproc_cmd_cfg_ns_params; + +/* + * Command to configure parameters for IIR tuning filter + */ + +#define AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS 0x0003 +#define AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS_LEN \ + sizeof(audpreproc_cmd_cfg_iir_tuning_filter_params) + +#define AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS 0x0000 +#define AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA 0x0001 + +typedef struct { + unsigned short cmd_id; + unsigned short active_flag; + unsigned short num_bands; + unsigned short numerator_coeff_b0_filter0_lsw; + unsigned short numerator_coeff_b0_filter0_msw; + unsigned short numerator_coeff_b1_filter0_lsw; + unsigned short numerator_coeff_b1_filter0_msw; + unsigned short numerator_coeff_b2_filter0_lsw; + unsigned short numerator_coeff_b2_filter0_msw; + unsigned short numerator_coeff_b0_filter1_lsw; + unsigned short numerator_coeff_b0_filter1_msw; + unsigned short numerator_coeff_b1_filter1_lsw; + unsigned short numerator_coeff_b1_filter1_msw; + unsigned short numerator_coeff_b2_filter1_lsw; + unsigned short numerator_coeff_b2_filter1_msw; + unsigned short numerator_coeff_b0_filter2_lsw; + unsigned short numerator_coeff_b0_filter2_msw; + unsigned short numerator_coeff_b1_filter2_lsw; + unsigned short numerator_coeff_b1_filter2_msw; + unsigned short numerator_coeff_b2_filter2_lsw; + unsigned short numerator_coeff_b2_filter2_msw; + unsigned short numerator_coeff_b0_filter3_lsw; + unsigned short numerator_coeff_b0_filter3_msw; + unsigned short numerator_coeff_b1_filter3_lsw; + unsigned short numerator_coeff_b1_filter3_msw; + unsigned short numerator_coeff_b2_filter3_lsw; + unsigned short numerator_coeff_b2_filter3_msw; + unsigned short denominator_coeff_a0_filter0_lsw; + unsigned short denominator_coeff_a0_filter0_msw; + unsigned short denominator_coeff_a1_filter0_lsw; + unsigned short denominator_coeff_a1_filter0_msw; + unsigned short denominator_coeff_a0_filter1_lsw; + unsigned short denominator_coeff_a0_filter1_msw; + unsigned short denominator_coeff_a1_filter1_lsw; + unsigned short denominator_coeff_a1_filter1_msw; + unsigned short denominator_coeff_a0_filter2_lsw; + unsigned short denominator_coeff_a0_filter2_msw; + unsigned short denominator_coeff_a1_filter2_lsw; + unsigned short denominator_coeff_a1_filter2_msw; + unsigned short denominator_coeff_a0_filter3_lsw; + unsigned short denominator_coeff_a0_filter3_msw; + unsigned short denominator_coeff_a1_filter3_lsw; + unsigned short denominator_coeff_a1_filter3_msw; + + unsigned short shift_factor_filter0; + unsigned short shift_factor_filter1; + unsigned short shift_factor_filter2; + unsigned short shift_factor_filter3; + + unsigned short channel_selected0; + unsigned short channel_selected1; + unsigned short channel_selected2; + unsigned short channel_selected3; +} __attribute__((packed))audpreproc_cmd_cfg_iir_tuning_filter_params; + +#endif diff --git a/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h new file mode 100644 index 000000000000..f40e41e76737 --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h @@ -0,0 +1,85 @@ +#ifndef QDSP5AUDPREPROCMSG_H +#define QDSP5AUDPREPROCMSG_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + A U D I O P R E P R O C E S S I N G M E S S A G E S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of messages + that are rcvd by AUDPREPROC Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + + $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreprocmsg.h#3 $ + +===========================================================================*/ + +/* + * ADSPREPROCTASK Messages + * AUDPREPROCTASK uses audPreProcUpRlist to communicate with ARM + * Location : MEMA + * Message Length : 2 + */ + +/* + * Message to indicate particular feature has been enabled or disabled + */ + + +#define AUDPREPROC_MSG_CMD_CFG_DONE_MSG 0x0000 +#define AUDPREPROC_MSG_CMD_CFG_DONE_MSG_LEN \ + sizeof(audpreproc_msg_cmd_cfg_done_msg) + +#define AUDPREPROC_MSG_TYPE_AGC 0x0000 +#define AUDPREPROC_MSG_TYPE_NOISE_REDUCTION 0x0001 +#define AUDPREPROC_MSG_TYPE_IIR_FILTER 0x0002 + + +#define AUDPREPROC_MSG_STATUS_FLAG_ENA -1 +#define AUDPREPROC_MSG_STATUS_FLAG_DIS 0x0000 + +typedef struct { + unsigned short type; + signed short status_flag; +} __attribute__((packed)) audpreproc_msg_cmd_cfg_done_msg; + + +/* + * Message to indicate particular feature has selected for wrong samp freq + */ + +#define AUDPREPROC_MSG_ERROR_MSG_ID 0x0001 +#define AUDPREPROC_MSG_ERROR_MSG_ID_LEN \ + sizeof(audpreproc_msg_error_msg_id) + +#define AUDPREPROC_MSG_ERR_INDEX_NS 0x0000 + +typedef struct { + unsigned short err_index; +} __attribute__((packed)) audpreproc_msg_error_msg_id; + +#endif diff --git a/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h new file mode 100644 index 000000000000..d03ee024ae91 --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h @@ -0,0 +1,176 @@ +#ifndef QDSP5AUDRECCMDI_H +#define QDSP5AUDRECCMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + A U D I O R E C O R D I N T E R N A L C O M M A N D S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by AUDREC Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + + $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audreccmdi.h#3 $ + +============================================================================*/ + +/* + * AUDRECTASK COMMANDS + * ARM uses 2 queues to communicate with the AUDRECTASK + * 1.uPAudRecCmdQueue + * Location :MEMC + * Buffer Size : 8 + * No of Buffers in a queue : 3 + * 2.audRecUpBitStreamQueue + * Location : MEMC + * Buffer Size : 4 + * No of buffers in a queue : 2 + */ + +/* + * Commands on uPAudRecCmdQueue + */ + +/* + * Command to initiate and terminate the audio recording section + */ + +#define AUDREC_CMD_CFG 0x0000 +#define AUDREC_CMD_CFG_LEN sizeof(audrec_cmd_cfg) + +#define AUDREC_CMD_TYPE_0_INDEX_WAV 0x0000 +#define AUDREC_CMD_TYPE_0_INDEX_AAC 0x0001 + +#define AUDREC_CMD_TYPE_0_ENA 0x4000 +#define AUDREC_CMD_TYPE_0_DIS 0x0000 + +#define AUDREC_CMD_TYPE_0_NOUPDATE 0x0000 +#define AUDREC_CMD_TYPE_0_UPDATE 0x8000 + +#define AUDREC_CMD_TYPE_1_INDEX_SBC 0x0002 + +#define AUDREC_CMD_TYPE_1_ENA 0x4000 +#define AUDREC_CMD_TYPE_1_DIS 0x0000 + +#define AUDREC_CMD_TYPE_1_NOUPDATE 0x0000 +#define AUDREC_CMD_TYPE_1_UPDATE 0x8000 + +typedef struct { + unsigned short cmd_id; + unsigned short type_0; + unsigned short type_1; +} __attribute__((packed)) audrec_cmd_cfg; + + +/* + * Command to configure the recording parameters for RecType0(AAC/WAV) encoder + */ + +#define AUDREC_CMD_AREC0PARAM_CFG 0x0001 +#define AUDREC_CMD_AREC0PARAM_CFG_LEN \ + sizeof(audrec_cmd_arec0param_cfg) + +#define AUDREC_CMD_SAMP_RATE_INDX_8000 0x000B +#define AUDREC_CMD_SAMP_RATE_INDX_11025 0x000A +#define AUDREC_CMD_SAMP_RATE_INDX_12000 0x0009 +#define AUDREC_CMD_SAMP_RATE_INDX_16000 0x0008 +#define AUDREC_CMD_SAMP_RATE_INDX_22050 0x0007 +#define AUDREC_CMD_SAMP_RATE_INDX_24000 0x0006 +#define AUDREC_CMD_SAMP_RATE_INDX_32000 0x0005 +#define AUDREC_CMD_SAMP_RATE_INDX_44100 0x0004 +#define AUDREC_CMD_SAMP_RATE_INDX_48000 0x0003 + +#define AUDREC_CMD_STEREO_MODE_MONO 0x0000 +#define AUDREC_CMD_STEREO_MODE_STEREO 0x0001 + +typedef struct { + unsigned short cmd_id; + unsigned short ptr_to_extpkt_buffer_msw; + unsigned short ptr_to_extpkt_buffer_lsw; + unsigned short buf_len; + unsigned short samp_rate_index; + unsigned short stereo_mode; + unsigned short rec_quality; +} __attribute__((packed)) audrec_cmd_arec0param_cfg; + +/* + * Command to configure the recording parameters for RecType1(SBC) encoder + */ + +#define AUDREC_CMD_AREC1PARAM_CFG 0x0002 +#define AUDREC_CMD_AREC1PARAM_CFG_LEN \ + sizeof(audrec_cmd_arec1param_cfg) + +#define AUDREC_CMD_PARAM_BUF_BLOCKS_4 0x0000 +#define AUDREC_CMD_PARAM_BUF_BLOCKS_8 0x0001 +#define AUDREC_CMD_PARAM_BUF_BLOCKS_12 0x0002 +#define AUDREC_CMD_PARAM_BUF_BLOCKS_16 0x0003 + +#define AUDREC_CMD_PARAM_BUF_SUB_BANDS_8 0x0010 +#define AUDREC_CMD_PARAM_BUF_MODE_MONO 0x0000 +#define AUDREC_CMD_PARAM_BUF_MODE_DUAL 0x0040 +#define AUDREC_CMD_PARAM_BUF_MODE_STEREO 0x0050 +#define AUDREC_CMD_PARAM_BUF_MODE_JSTEREO 0x0060 +#define AUDREC_CMD_PARAM_BUF_LOUDNESS 0x0000 +#define AUDREC_CMD_PARAM_BUF_SNR 0x0100 +#define AUDREC_CMD_PARAM_BUF_BASIC_VER 0x0000 + +typedef struct { + unsigned short cmd_id; + unsigned short ptr_to_extpkt_buffer_msw; + unsigned short ptr_to_extpkt_buffer_lsw; + unsigned short buf_len; + unsigned short param_buf; + unsigned short bit_rate_0; + unsigned short bit_rate_1; +} __attribute__((packed)) audrec_cmd_arec1param_cfg; + + +/* + * Commands on audRecUpBitStreamQueue + */ + +/* + * Command to indicate the current packet read count + */ + +#define AUDREC_CMD_PACKET_EXT_PTR 0x0000 +#define AUDREC_CMD_PACKET_EXT_PTR_LEN \ + sizeof(audrec_cmd_packet_ext_ptr) + +#define AUDREC_CMD_TYPE_0 0x0000 +#define AUDREC_CMD_TYPE_1 0x0001 + +typedef struct { + unsigned short cmd_id; + unsigned short type; + unsigned short curr_rec_count_msw; + unsigned short curr_rec_count_lsw; +} __attribute__((packed)) audrec_cmd_packet_ext_ptr; + +#endif diff --git a/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h new file mode 100644 index 000000000000..bb6eb5093cf5 --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h @@ -0,0 +1,127 @@ +#ifndef QDSP5AUDRECMSGI_H +#define QDSP5AUDRECMSGI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + A U D I O R E C O R D M E S S A G E S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of messages + that are sent by AUDREC Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + + $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audrecmsg.h#3 $ + +============================================================================*/ + +/* + * AUDRECTASK MESSAGES + * AUDRECTASK uses audRecUpRlist to communicate with ARM + * Location : MEMC + * Buffer size : 4 + * No of buffers in a queue : 2 + */ + +/* + * Message to notify that config command is done + */ + +#define AUDREC_MSG_CMD_CFG_DONE_MSG 0x0002 +#define AUDREC_MSG_CMD_CFG_DONE_MSG_LEN \ + sizeof(audrec_msg_cmd_cfg_done_msg) + + +#define AUDREC_MSG_CFG_DONE_TYPE_0_ENA 0x4000 +#define AUDREC_MSG_CFG_DONE_TYPE_0_DIS 0x0000 + +#define AUDREC_MSG_CFG_DONE_TYPE_0_NO_UPDATE 0x0000 +#define AUDREC_MSG_CFG_DONE_TYPE_0_UPDATE 0x8000 + +#define AUDREC_MSG_CFG_DONE_TYPE_1_ENA 0x4000 +#define AUDREC_MSG_CFG_DONE_TYPE_1_DIS 0x0000 + +#define AUDREC_MSG_CFG_DONE_TYPE_1_NO_UPDATE 0x0000 +#define AUDREC_MSG_CFG_DONE_TYPE_1_UPDATE 0x8000 + +typedef struct { + unsigned short type_0; + unsigned short type_1; +} __attribute__((packed))audrec_msg_cmd_cfg_done_msg; + + +/* + * Message to notify arec0/1 cfg done and recording params revd by task + */ + +#define AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG 0x0003 +#define AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG_LEN \ + sizeof(audrec_msg_cmd_arec_param_cfg_done_msg) + +#define AUDREC_MSG_AREC_PARAM_TYPE_0 0x0000 +#define AUDREC_MSG_AREC_PARAM_TYPE_1 0x0001 + +typedef struct { + unsigned short type; +} __attribute__((packed))audrec_msg_cmd_arec_param_cfg_done_msg; + + +/* + * Message to notify no more buffers are available in ext mem to DME + */ + +#define AUDREC_MSG_FATAL_ERR_MSG 0x0004 +#define AUDREC_MSG_FATAL_ERR_MSG_LEN \ + sizeof(audrec_msg_fatal_err_msg) + +#define AUDREC_MSG_FATAL_ERR_TYPE_0 0x0000 +#define AUDREC_MSG_FATAL_ERR_TYPE_1 0x0001 + +typedef struct { + unsigned short type; +} __attribute__((packed))audrec_msg_fatal_err_msg; + +/* + * Message to notify DME deliverd the encoded pkt to ext pkt buffer + */ + +#define AUDREC_MSG_PACKET_READY_MSG 0x0005 +#define AUDREC_MSG_PACKET_READY_MSG_LEN \ + sizeof(audrec_msg_packet_ready_msg) + +#define AUDREC_MSG_PACKET_READY_TYPE_0 0x0000 +#define AUDREC_MSG_PACKET_READY_TYPE_1 0x0001 + +typedef struct { + unsigned short type; + unsigned short pkt_counter_msw; + unsigned short pkt_counter_lsw; + unsigned short pkt_read_cnt_msw; + unsigned short pkt_read_cnt_lsw; +} __attribute__((packed))audrec_msg_packet_ready_msg; + +#endif diff --git a/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h new file mode 100644 index 000000000000..574ad6bbcade --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h @@ -0,0 +1,376 @@ +#ifndef QDSP5VIDJPEGCMDI_H +#define QDSP5VIDJPEGCMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + J P E G I N T E R N A L C O M M A N D S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by JPEG Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ +Revision History: +when who what, where, why +-------- --- ---------------------------------------------------------- +06/09/08 sv initial version +===========================================================================*/ + +/* + * ARM to JPEG configuration commands are passed through the + * uPJpegCfgCmdQueue + */ + +/* + * Command to configure JPEG Encoder + */ + +#define JPEG_CMD_ENC_CFG 0x0000 +#define JPEG_CMD_ENC_CFG_LEN sizeof(jpeg_cmd_enc_cfg) + +#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_0 0x0000 +#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_90 0x0100 +#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_180 0x0200 +#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_270 0x0300 +#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_M 0x0003 +#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V2 0x0000 +#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V1 0x0001 +#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H1V2 0x0002 + +#define JPEG_CMD_IP_SIZE_CFG_LUMA_HEIGHT_M 0x0000FFFF +#define JPEG_CMD_IP_SIZE_CFG_LUMA_WIDTH_M 0xFFFF0000 +#define JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_ENA 0x0001 +#define JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_DIS 0x0000 + +#define JPEG_CMD_FRAG_SIZE_LUMA_HEIGHT_M 0xFFFF + +typedef struct { + unsigned int cmd_id; + unsigned int process_cfg; + unsigned int ip_size_cfg; + unsigned int op_size_cfg; + unsigned int frag_cfg; + unsigned int frag_cfg_part[16]; + + unsigned int part_num; + + unsigned int op_buf_0_cfg_part1; + unsigned int op_buf_0_cfg_part2; + unsigned int op_buf_1_cfg_part1; + unsigned int op_buf_1_cfg_part2; + + unsigned int luma_qunt_table[32]; + unsigned int chroma_qunt_table[32]; + + unsigned int upsamp_ip_size_cfg; + unsigned int upsamp_ip_frame_off; + unsigned int upsamp_pp_filter_coeff[64]; +} __attribute__((packed)) jpeg_cmd_enc_cfg; + +/* + * Command to configure JPEG Decoder + */ + +#define JPEG_CMD_DEC_CFG 0x0001 +#define JPEG_CMD_DEC_CFG_LEN sizeof(jpeg_cmd_dec_cfg) + +#define JPEG_CMD_DEC_OP_DATA_FORMAT_M 0x0001 +#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2 0x0000 +#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V1 0x0001 + +#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_8 0x000000 +#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_4 0x010000 +#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_2 0x020000 +#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_1 0x030000 + +#define JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_NOT_FINAL 0x0000 +#define JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_FINAL 0x0001 + + +typedef struct { + unsigned int cmd_id; + unsigned int img_dimension_cfg; + unsigned int op_data_format; + unsigned int restart_interval; + unsigned int ip_buf_partition_num; + unsigned int ip_stream_buf_cfg_part1; + unsigned int ip_stream_buf_cfg_part2; + unsigned int ip_stream_buf_cfg_part3; + unsigned int op_stream_buf_0_cfg_part1; + unsigned int op_stream_buf_0_cfg_part2; + unsigned int op_stream_buf_0_cfg_part3; + unsigned int op_stream_buf_1_cfg_part1; + unsigned int op_stream_buf_1_cfg_part2; + unsigned int op_stream_buf_1_cfg_part3; + unsigned int luma_qunt_table_0_3; + unsigned int luma_qunt_table_4_7; + unsigned int luma_qunt_table_8_11; + unsigned int luma_qunt_table_12_15; + unsigned int luma_qunt_table_16_19; + unsigned int luma_qunt_table_20_23; + unsigned int luma_qunt_table_24_27; + unsigned int luma_qunt_table_28_31; + unsigned int luma_qunt_table_32_35; + unsigned int luma_qunt_table_36_39; + unsigned int luma_qunt_table_40_43; + unsigned int luma_qunt_table_44_47; + unsigned int luma_qunt_table_48_51; + unsigned int luma_qunt_table_52_55; + unsigned int luma_qunt_table_56_59; + unsigned int luma_qunt_table_60_63; + unsigned int chroma_qunt_table_0_3; + unsigned int chroma_qunt_table_4_7; + unsigned int chroma_qunt_table_8_11; + unsigned int chroma_qunt_table_12_15; + unsigned int chroma_qunt_table_16_19; + unsigned int chroma_qunt_table_20_23; + unsigned int chroma_qunt_table_24_27; + unsigned int chroma_qunt_table_28_31; + unsigned int chroma_qunt_table_32_35; + unsigned int chroma_qunt_table_36_39; + unsigned int chroma_qunt_table_40_43; + unsigned int chroma_qunt_table_44_47; + unsigned int chroma_qunt_table_48_51; + unsigned int chroma_qunt_table_52_55; + unsigned int chroma_qunt_table_56_59; + unsigned int chroma_qunt_table_60_63; + unsigned int luma_dc_hm_code_cnt_table_0_3; + unsigned int luma_dc_hm_code_cnt_table_4_7; + unsigned int luma_dc_hm_code_cnt_table_8_11; + unsigned int luma_dc_hm_code_cnt_table_12_15; + unsigned int luma_dc_hm_code_val_table_0_3; + unsigned int luma_dc_hm_code_val_table_4_7; + unsigned int luma_dc_hm_code_val_table_8_11; + unsigned int chroma_dc_hm_code_cnt_table_0_3; + unsigned int chroma_dc_hm_code_cnt_table_4_7; + unsigned int chroma_dc_hm_code_cnt_table_8_11; + unsigned int chroma_dc_hm_code_cnt_table_12_15; + unsigned int chroma_dc_hm_code_val_table_0_3; + unsigned int chroma_dc_hm_code_val_table_4_7; + unsigned int chroma_dc_hm_code_val_table_8_11; + unsigned int luma_ac_hm_code_cnt_table_0_3; + unsigned int luma_ac_hm_code_cnt_table_4_7; + unsigned int luma_ac_hm_code_cnt_table_8_11; + unsigned int luma_ac_hm_code_cnt_table_12_15; + unsigned int luma_ac_hm_code_val_table_0_3; + unsigned int luma_ac_hm_code_val_table_4_7; + unsigned int luma_ac_hm_code_val_table_8_11; + unsigned int luma_ac_hm_code_val_table_12_15; + unsigned int luma_ac_hm_code_val_table_16_19; + unsigned int luma_ac_hm_code_val_table_20_23; + unsigned int luma_ac_hm_code_val_table_24_27; + unsigned int luma_ac_hm_code_val_table_28_31; + unsigned int luma_ac_hm_code_val_table_32_35; + unsigned int luma_ac_hm_code_val_table_36_39; + unsigned int luma_ac_hm_code_val_table_40_43; + unsigned int luma_ac_hm_code_val_table_44_47; + unsigned int luma_ac_hm_code_val_table_48_51; + unsigned int luma_ac_hm_code_val_table_52_55; + unsigned int luma_ac_hm_code_val_table_56_59; + unsigned int luma_ac_hm_code_val_table_60_63; + unsigned int luma_ac_hm_code_val_table_64_67; + unsigned int luma_ac_hm_code_val_table_68_71; + unsigned int luma_ac_hm_code_val_table_72_75; + unsigned int luma_ac_hm_code_val_table_76_79; + unsigned int luma_ac_hm_code_val_table_80_83; + unsigned int luma_ac_hm_code_val_table_84_87; + unsigned int luma_ac_hm_code_val_table_88_91; + unsigned int luma_ac_hm_code_val_table_92_95; + unsigned int luma_ac_hm_code_val_table_96_99; + unsigned int luma_ac_hm_code_val_table_100_103; + unsigned int luma_ac_hm_code_val_table_104_107; + unsigned int luma_ac_hm_code_val_table_108_111; + unsigned int luma_ac_hm_code_val_table_112_115; + unsigned int luma_ac_hm_code_val_table_116_119; + unsigned int luma_ac_hm_code_val_table_120_123; + unsigned int luma_ac_hm_code_val_table_124_127; + unsigned int luma_ac_hm_code_val_table_128_131; + unsigned int luma_ac_hm_code_val_table_132_135; + unsigned int luma_ac_hm_code_val_table_136_139; + unsigned int luma_ac_hm_code_val_table_140_143; + unsigned int luma_ac_hm_code_val_table_144_147; + unsigned int luma_ac_hm_code_val_table_148_151; + unsigned int luma_ac_hm_code_val_table_152_155; + unsigned int luma_ac_hm_code_val_table_156_159; + unsigned int luma_ac_hm_code_val_table_160_161; + unsigned int chroma_ac_hm_code_cnt_table_0_3; + unsigned int chroma_ac_hm_code_cnt_table_4_7; + unsigned int chroma_ac_hm_code_cnt_table_8_11; + unsigned int chroma_ac_hm_code_cnt_table_12_15; + unsigned int chroma_ac_hm_code_val_table_0_3; + unsigned int chroma_ac_hm_code_val_table_4_7; + unsigned int chroma_ac_hm_code_val_table_8_11; + unsigned int chroma_ac_hm_code_val_table_12_15; + unsigned int chroma_ac_hm_code_val_table_16_19; + unsigned int chroma_ac_hm_code_val_table_20_23; + unsigned int chroma_ac_hm_code_val_table_24_27; + unsigned int chroma_ac_hm_code_val_table_28_31; + unsigned int chroma_ac_hm_code_val_table_32_35; + unsigned int chroma_ac_hm_code_val_table_36_39; + unsigned int chroma_ac_hm_code_val_table_40_43; + unsigned int chroma_ac_hm_code_val_table_44_47; + unsigned int chroma_ac_hm_code_val_table_48_51; + unsigned int chroma_ac_hm_code_val_table_52_55; + unsigned int chroma_ac_hm_code_val_table_56_59; + unsigned int chroma_ac_hm_code_val_table_60_63; + unsigned int chroma_ac_hm_code_val_table_64_67; + unsigned int chroma_ac_hm_code_val_table_68_71; + unsigned int chroma_ac_hm_code_val_table_72_75; + unsigned int chroma_ac_hm_code_val_table_76_79; + unsigned int chroma_ac_hm_code_val_table_80_83; + unsigned int chroma_ac_hm_code_val_table_84_87; + unsigned int chroma_ac_hm_code_val_table_88_91; + unsigned int chroma_ac_hm_code_val_table_92_95; + unsigned int chroma_ac_hm_code_val_table_96_99; + unsigned int chroma_ac_hm_code_val_table_100_103; + unsigned int chroma_ac_hm_code_val_table_104_107; + unsigned int chroma_ac_hm_code_val_table_108_111; + unsigned int chroma_ac_hm_code_val_table_112_115; + unsigned int chroma_ac_hm_code_val_table_116_119; + unsigned int chroma_ac_hm_code_val_table_120_123; + unsigned int chroma_ac_hm_code_val_table_124_127; + unsigned int chroma_ac_hm_code_val_table_128_131; + unsigned int chroma_ac_hm_code_val_table_132_135; + unsigned int chroma_ac_hm_code_val_table_136_139; + unsigned int chroma_ac_hm_code_val_table_140_143; + unsigned int chroma_ac_hm_code_val_table_144_147; + unsigned int chroma_ac_hm_code_val_table_148_151; + unsigned int chroma_ac_hm_code_val_table_152_155; + unsigned int chroma_ac_hm_code_val_table_156_159; + unsigned int chroma_ac_hm_code_val_table_160_161; +} __attribute__((packed)) jpeg_cmd_dec_cfg; + + +/* + * ARM to JPEG configuration commands are passed through the + * uPJpegActionCmdQueue + */ + +/* + * Command to start the encode process + */ + +#define JPEG_CMD_ENC_ENCODE 0x0000 +#define JPEG_CMD_ENC_ENCODE_LEN sizeof(jpeg_cmd_enc_encode) + + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) jpeg_cmd_enc_encode; + + +/* + * Command to transition from current state of encoder to IDLE state + */ + +#define JPEG_CMD_ENC_IDLE 0x0001 +#define JPEG_CMD_ENC_IDLE_LEN sizeof(jpeg_cmd_enc_idle) + + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) jpeg_cmd_enc_idle; + + +/* + * Command to inform the encoder that another buffer is ready + */ + +#define JPEG_CMD_ENC_OP_CONSUMED 0x0002 +#define JPEG_CMD_ENC_OP_CONSUMED_LEN sizeof(jpeg_cmd_enc_op_consumed) + + +typedef struct { + unsigned int cmd_id; + unsigned int op_buf_addr; + unsigned int op_buf_size; +} __attribute__((packed)) jpeg_cmd_enc_op_consumed; + + +/* + * Command to start the decoding process + */ + +#define JPEG_CMD_DEC_DECODE 0x0003 +#define JPEG_CMD_DEC_DECODE_LEN sizeof(jpeg_cmd_dec_decode) + + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) jpeg_cmd_dec_decode; + + +/* + * Command to transition from the current state of decoder to IDLE + */ + +#define JPEG_CMD_DEC_IDLE 0x0004 +#define JPEG_CMD_DEC_IDLE_LEN sizeof(jpeg_cmd_dec_idle) + + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) jpeg_cmd_dec_idle; + + +/* + * Command to inform that an op buffer is ready for use + */ + +#define JPEG_CMD_DEC_OP_CONSUMED 0x0005 +#define JPEG_CMD_DEC_OP_CONSUMED_LEN sizeof(jpeg_cmd_dec_op_consumed) + + +typedef struct { + unsigned int cmd_id; + unsigned int luma_op_buf_addr; + unsigned int luma_op_buf_size; + unsigned int chroma_op_buf_addr; +} __attribute__((packed)) jpeg_cmd_dec_op_consumed; + + +/* + * Command to pass a new ip buffer to the jpeg decoder + */ + +#define JPEG_CMD_DEC_IP 0x0006 +#define JPEG_CMD_DEC_IP_LEN sizeof(jpeg_cmd_dec_ip_len) + +#define JPEG_CMD_EOI_INDICATOR_NOT_END 0x0000 +#define JPEG_CMD_EOI_INDICATOR_END 0x0001 + +typedef struct { + unsigned int cmd_id; + unsigned int ip_buf_addr; + unsigned int ip_buf_size; + unsigned int eoi_indicator; +} __attribute__((packed)) jpeg_cmd_dec_ip; + + + +#endif diff --git a/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h new file mode 100644 index 000000000000..d11aa3fbccb6 --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h @@ -0,0 +1,177 @@ +#ifndef QDSP5VIDJPEGMSGI_H +#define QDSP5VIDJPEGMSGI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + J P E G I N T E R N A L M E S S A G E S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of messages + that are sent by JPEG Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ +Revision History: + +when who what, where, why +-------- --- ---------------------------------------------------------- +05/10/08 sv initial version +===========================================================================*/ + +/* + * Messages from JPEG task to ARM through jpeguPMsgQueue + */ + +/* + * Message is ACK for CMD_JPEGE_ENCODE cmd + */ + +#define JPEG_MSG_ENC_ENCODE_ACK 0x0000 +#define JPEG_MSG_ENC_ENCODE_ACK_LEN \ + sizeof(jpeg_msg_enc_encode_ack) + +typedef struct { +} __attribute__((packed)) jpeg_msg_enc_encode_ack; + + +/* + * Message informs the up when op buffer is ready for consumption and + * when encoding is complete or errors + */ + +#define JPEG_MSG_ENC_OP_PRODUCED 0x0001 +#define JPEG_MSG_ENC_OP_PRODUCED_LEN \ + sizeof(jpeg_msg_enc_op_produced) + +#define JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_PROGRESS 0x0000 +#define JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_COMPLETE 0x0001 +#define JPEG_MSGOP_OP_BUF_STATUS_ENC_ERR 0x10000 + +typedef struct { + unsigned int op_buf_addr; + unsigned int op_buf_size; + unsigned int op_buf_status; +} __attribute__((packed)) jpeg_msg_enc_op_produced; + + +/* + * Message to ack CMD_JPEGE_IDLE + */ + +#define JPEG_MSG_ENC_IDLE_ACK 0x0002 +#define JPEG_MSG_ENC_IDLE_ACK_LEN sizeof(jpeg_msg_enc_idle_ack) + + +typedef struct { +} __attribute__ ((packed)) jpeg_msg_enc_idle_ack; + + +/* + * Message to indicate the illegal command + */ + +#define JPEG_MSG_ENC_ILLEGAL_COMMAND 0x0003 +#define JPEG_MSG_ENC_ILLEGAL_COMMAND_LEN \ + sizeof(jpeg_msg_enc_illegal_command) + +typedef struct { + unsigned int status; +} __attribute__((packed)) jpeg_msg_enc_illegal_command; + + +/* + * Message to ACK CMD_JPEGD_DECODE + */ + +#define JPEG_MSG_DEC_DECODE_ACK 0x0004 +#define JPEG_MSG_DEC_DECODE_ACK_LEN \ + sizeof(jpeg_msg_dec_decode_ack) + + +typedef struct { +} __attribute__((packed)) jpeg_msg_dec_decode_ack; + + +/* + * Message to inform up that an op buffer is ready for consumption and when + * decoding is complete or an error occurs + */ + +#define JPEG_MSG_DEC_OP_PRODUCED 0x0005 +#define JPEG_MSG_DEC_OP_PRODUCED_LEN \ + sizeof(jpeg_msg_dec_op_produced) + +#define JPEG_MSG_DEC_OP_BUF_STATUS_PROGRESS 0x0000 +#define JPEG_MSG_DEC_OP_BUF_STATUS_DONE 0x0001 + +typedef struct { + unsigned int luma_op_buf_addr; + unsigned int chroma_op_buf_addr; + unsigned int num_mcus; + unsigned int op_buf_status; +} __attribute__((packed)) jpeg_msg_dec_op_produced; + +/* + * Message to ack CMD_JPEGD_IDLE cmd + */ + +#define JPEG_MSG_DEC_IDLE_ACK 0x0006 +#define JPEG_MSG_DEC_IDLE_ACK_LEN sizeof(jpeg_msg_dec_idle_ack) + + +typedef struct { +} __attribute__((packed)) jpeg_msg_dec_idle_ack; + + +/* + * Message to indicate illegal cmd was received + */ + +#define JPEG_MSG_DEC_ILLEGAL_COMMAND 0x0007 +#define JPEG_MSG_DEC_ILLEGAL_COMMAND_LEN \ + sizeof(jpeg_msg_dec_illegal_command) + + +typedef struct { + unsigned int status; +} __attribute__((packed)) jpeg_msg_dec_illegal_command; + +/* + * Message to request up for the next segment of ip bit stream + */ + +#define JPEG_MSG_DEC_IP_REQUEST 0x0008 +#define JPEG_MSG_DEC_IP_REQUEST_LEN \ + sizeof(jpeg_msg_dec_ip_request) + + +typedef struct { +} __attribute__((packed)) jpeg_msg_dec_ip_request; + + + +#endif diff --git a/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h new file mode 100644 index 000000000000..6c76e2c20cf4 --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h @@ -0,0 +1,82 @@ +#ifndef QDSP5LPMCMDI_H +#define QDSP5LPMCMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + L P M I N T E R N A L C O M M A N D S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by LPM Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + + +$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ +Revision History: + +when who what, where, why +-------- --- ---------------------------------------------------------- +06/12/08 sv initial version +===========================================================================*/ + + +/* + * Command to start LPM processing based on the config params + */ + +#define LPM_CMD_START 0x0000 +#define LPM_CMD_START_LEN sizeof(lpm_cmd_start) + +#define LPM_CMD_SPATIAL_FILTER_PART_OPMODE_0 0x00000000 +#define LPM_CMD_SPATIAL_FILTER_PART_OPMODE_1 0x00010000 +typedef struct { + unsigned int cmd_id; + unsigned int ip_data_cfg_part1; + unsigned int ip_data_cfg_part2; + unsigned int ip_data_cfg_part3; + unsigned int ip_data_cfg_part4; + unsigned int op_data_cfg_part1; + unsigned int op_data_cfg_part2; + unsigned int op_data_cfg_part3; + unsigned int spatial_filter_part[32]; +} __attribute__((packed)) lpm_cmd_start; + + + +/* + * Command to stop LPM processing + */ + +#define LPM_CMD_IDLE 0x0001 +#define LPM_CMD_IDLE_LEN sizeof(lpm_cmd_idle) + +typedef struct { + unsigned int cmd_id; +} __attribute__((packed)) lpm_cmd_idle; + + +#endif diff --git a/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h new file mode 100644 index 000000000000..3d1039d6ba42 --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h @@ -0,0 +1,80 @@ +#ifndef QDSP5LPMMSGI_H +#define QDSP5LPMMSGI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + L P M I N T E R N A L M E S S A G E S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by LPM Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ +Revision History: + +when who what, where, why +-------- --- ---------------------------------------------------------- +06/12/08 sv initial version +===========================================================================*/ + +/* + * Message to acknowledge CMD_LPM_IDLE command + */ + +#define LPM_MSG_IDLE_ACK 0x0000 +#define LPM_MSG_IDLE_ACK_LEN sizeof(lpm_msg_idle_ack) + +typedef struct { +} __attribute__((packed)) lpm_msg_idle_ack; + + +/* + * Message to acknowledge CMD_LPM_START command + */ + + +#define LPM_MSG_START_ACK 0x0001 +#define LPM_MSG_START_ACK_LEN sizeof(lpm_msg_start_ack) + + +typedef struct { +} __attribute__((packed)) lpm_msg_start_ack; + + +/* + * Message to notify the ARM that LPM processing is complete + */ + +#define LPM_MSG_DONE 0x0002 +#define LPM_MSG_DONE_LEN sizeof(lpm_msg_done) + +typedef struct { +} __attribute__((packed)) lpm_msg_done; + + +#endif diff --git a/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h new file mode 100644 index 000000000000..3a32ee99c6e4 --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h @@ -0,0 +1,235 @@ +#ifndef QDSP5VIDDECCMDI_H +#define QDSP5VIDDECCMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + V I D E O D E C O D E R I N T E R N A L C O M M A N D S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by VIDDEC Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdeccmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ +Revision History: + +when who what, where, why +-------- --- ---------------------------------------------------------- +05/10/08 ac initial version +===========================================================================*/ + + +/* + * Command to inform VIDDEC that new subframe packet is ready + */ + +#define VIDDEC_CMD_SUBFRAME_PKT 0x0000 +#define VIDDEC_CMD_SUBFRAME_PKT_LEN \ + sizeof(viddec_cmd_subframe_pkt) + +#define VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DM 0x0000 +#define VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DMA 0x0001 + +#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_CONTI 0x0000 +#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST 0x0001 +#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_LAST 0x0002 +#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST_AND_LAST 0x0003 + +#define VIDDEC_CMD_CODEC_SELECTION_WORD_MPEG_4 0x0000 +#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_P0 0x0001 +#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_264 0x0002 +#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_p3 0x0003 +#define VIDDEC_CMD_CODEC_SELECTION_WORD_RV9 0x0004 +#define VIDDEC_CMD_CODEC_SELECTION_WORD_WMV9 0x0005 +#define VIDDEC_CMD_CODEC_SELECTION_WORD_SMCDB 0x0006 +#define VIDDEC_CMD_CODEC_SELECTION_WORD_QFRE 0x0007 +#define VIDDEC_CMD_CODEC_SELECTION_WORD_VLD 0x0008 + +typedef struct { + unsigned short cmd_id; + unsigned short packet_seq_number; + unsigned short codec_instance_id; + unsigned short subframe_packet_size_high; + unsigned short subframe_packet_size_low; + unsigned short subframe_packet_high; + unsigned short subframe_packet_low; + unsigned short subframe_packet_partition; + unsigned short statistics_packet_size_high; + unsigned short statistics_packet_size_low; + unsigned short statistics_packet_high; + unsigned short statistics_packet_low; + unsigned short statistics_partition; + unsigned short subframe_info_1; + unsigned short subframe_info_0; + unsigned short codec_selection_word; + unsigned short num_mbs; +} __attribute__((packed)) viddec_cmd_subframe_pkt; + + +/* + * Command to inform VIDDEC task that post processing is required for the frame + */ + +#define VIDDEC_CMD_PP_ENABLE 0x0001 +#define VIDDEC_CMD_PP_ENABLE_LEN \ + sizeof(viddec_cmd_pp_enable) + +#define VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DM 0x0000 +#define VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DMA 0x0001 + +typedef struct { + unsigned short cmd_id; + unsigned short packet_seq_num; + unsigned short codec_instance_id; + unsigned short postproc_info_0; + unsigned short codec_selection_word; + unsigned short pp_output_addr_high; + unsigned short pp_output_addr_low; + unsigned short postproc_info_1; + unsigned short load_sharing_packet_size_high; + unsigned short load_sharing_packet_size_low; + unsigned short load_sharing_packet_high; + unsigned short load_sharing_packet_low; + unsigned short load_sharing_partition; + unsigned short pp_param_0; + unsigned short pp_param_1; + unsigned short pp_param_2; + unsigned short pp_param_3; +} __attribute__((packed)) viddec_cmd_pp_enable; + + +/* + * FRAME Header Packet : It is at the start of new frame + */ + +#define VIDDEC_CMD_FRAME_HEADER_PACKET 0x0002 +#define VIDDEC_CMD_FRAME_HEADER_PACKET_LEN \ + sizeof(viddec_cmd_frame_header_packet) + +#define VIDDEC_CMD_FRAME_INFO_0_ERROR_SKIP 0x0000 +#define VIDDEC_CMD_FRAME_INFO_0_ERROR_BLACK 0x0800 + +typedef struct { + unsigned short packet_id; + unsigned short x_dimension; + unsigned short y_dimension; + unsigned short line_width; + unsigned short frame_info_0; + unsigned short frame_buffer_0_high; + unsigned short frame_buffer_0_low; + unsigned short frame_buffer_1_high; + unsigned short frame_buffer_1_low; + unsigned short frame_buffer_2_high; + unsigned short frame_buffer_2_low; + unsigned short frame_buffer_3_high; + unsigned short frame_buffer_3_low; + unsigned short frame_buffer_4_high; + unsigned short frame_buffer_4_low; + unsigned short frame_buffer_5_high; + unsigned short frame_buffer_5_low; + unsigned short frame_buffer_6_high; + unsigned short frame_buffer_6_low; + unsigned short frame_buffer_7_high; + unsigned short frame_buffer_7_low; + unsigned short frame_buffer_8_high; + unsigned short frame_buffer_8_low; + unsigned short frame_buffer_9_high; + unsigned short frame_buffer_9_low; + unsigned short frame_buffer_10_high; + unsigned short frame_buffer_10_low; + unsigned short frame_buffer_11_high; + unsigned short frame_buffer_11_low; + unsigned short frame_buffer_12_high; + unsigned short frame_buffer_12_low; + unsigned short frame_buffer_13_high; + unsigned short frame_buffer_13_low; + unsigned short frame_buffer_14_high; + unsigned short frame_buffer_14_low; + unsigned short frame_buffer_15_high; + unsigned short frame_buffer_15_low; + unsigned short output_frame_buffer_high; + unsigned short output_frame_buffer_low; + unsigned short end_of_packet_marker; +} __attribute__((packed)) viddec_cmd_frame_header_packet; + + +/* + * SLICE HEADER PACKET + * I-Slice and P-Slice + */ + +#define VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE 0x0003 +#define VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE_LEN \ + sizeof(viddec_cmd_slice_header_pkt_islice) + +#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_PSLICE 0x0000 +#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_BSLICE 0x0100 +#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_ISLICE 0x0200 +#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SPSLICE 0x0300 +#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SISLICE 0x0400 +#define VIDDEC_CMD_ISLICE_INFO_1_NOPADDING 0x0000 +#define VIDDEC_CMD_ISLICE_INFO_1_PADDING 0x0800 + +#define VIDDEC_CMD_ISLICE_EOP_MARKER 0x7FFF + +typedef struct { + unsigned short cmd_id; + unsigned short packet_id; + unsigned short slice_info_0; + unsigned short slice_info_1; + unsigned short slice_info_2; + unsigned short num_bytes_in_rbsp_high; + unsigned short num_bytes_in_rbsp_low; + unsigned short num_bytes_in_rbsp_consumed; + unsigned short end_of_packet_marker; +} __attribute__((packed)) viddec_cmd_slice_header_pkt_islice; + + +#define VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE 0x0003 +#define VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE_LEN \ + sizeof(viddec_cmd_slice_header_pkt_pslice) + + +typedef struct { + unsigned short cmd_id; + unsigned short packet_id; + unsigned short slice_info_0; + unsigned short slice_info_1; + unsigned short slice_info_2; + unsigned short slice_info_3; + unsigned short refidx_l0_map_tab_info_0; + unsigned short refidx_l0_map_tab_info_1; + unsigned short refidx_l0_map_tab_info_2; + unsigned short refidx_l0_map_tab_info_3; + unsigned short num_bytes_in_rbsp_high; + unsigned short num_bytes_in_rbsp_low; + unsigned short num_bytes_in_rbsp_consumed; + unsigned short end_of_packet_marker; +} __attribute__((packed)) viddec_cmd_slice_header_pkt_pslice; + + +#endif diff --git a/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h new file mode 100644 index 000000000000..c1744c1644dd --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h @@ -0,0 +1,107 @@ +#ifndef QDSP5VIDDECMSGI_H +#define QDSP5VIDDECMSGI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + V I D E O D E C O D E R I N T E R N A L M E S S A G E S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of messages + that are sent by VIDDEC Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdecmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ +Revision History: + +when who what, where, why +-------- --- ---------------------------------------------------------- +05/10/08 ac initial version +===========================================================================*/ + +/* + * Message to inform ARM which VDEC_SUBFRAME_PKT_CMD processed by VIDDEC TASK + */ + +#define VIDDEC_MSG_SUBF_DONE 0x0000 +#define VIDDEC_MSG_SUBF_DONE_LEN \ + sizeof(viddec_msg_subf_done) + +typedef struct { + unsigned short packet_seq_number; + unsigned short codec_instance_id; +} __attribute__((packed)) viddec_msg_subf_done; + + +/* + * Message to inform ARM one frame has been decoded + */ + +#define VIDDEC_MSG_FRAME_DONE 0x0001 +#define VIDDEC_MSG_FRAME_DONE_LEN \ + sizeof(viddec_msg_frame_done) + +typedef struct { + unsigned short packet_seq_number; + unsigned short codec_instance_id; +} __attribute__((packed)) viddec_msg_frame_done; + + +/* + * Message to inform ARM that post processing frame has been decoded + */ + +#define VIDDEC_MSG_PP_ENABLE_CMD_DONE 0x0002 +#define VIDDEC_MSG_PP_ENABLE_CMD_DONE_LEN \ + sizeof(viddec_msg_pp_enable_cmd_done) + +typedef struct { + unsigned short packet_seq_number; + unsigned short codec_instance_id; +} __attribute__((packed)) viddec_msg_pp_enable_cmd_done; + + +/* + * Message to inform ARM that one post processing frame has been decoded + */ + + +#define VIDDEC_MSG_PP_FRAME_DONE 0x0003 +#define VIDDEC_MSG_PP_FRAME_DONE_LEN \ + sizeof(viddec_msg_pp_frame_done) + +#define VIDDEC_MSG_DISP_WORTHY_DISP 0x0000 +#define VIDDEC_MSG_DISP_WORTHY_DISP_NONE 0xFFFF + + +typedef struct { + unsigned short packet_seq_number; + unsigned short codec_instance_id; + unsigned short display_worthy; +} __attribute__((packed)) viddec_msg_pp_frame_done; + + +#endif diff --git a/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h new file mode 100644 index 000000000000..819544d186da --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h @@ -0,0 +1,212 @@ +#ifndef QDSP5VIDENCCMDI_H +#define QDSP5VIDENCCMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + V I D E O E N C O D E R I N T E R N A L C O M M A N D S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by VIDENC Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 2008 by QUALCOMM, Incorporated. +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +Revision History: + +when who what, where, why +-------- --- ---------------------------------------------------------- +09/25/08 umeshp initial version +===========================================================================*/ + + #define VIDENC_CMD_CFG 0x0000 + #define VIDENC_CMD_ACTIVE 0x0001 + #define VIDENC_CMD_IDLE 0x0002 + #define VIDENC_CMD_FRAME_START 0x0003 + #define VIDENC_CMD_STATUS_QUERY 0x0004 + #define VIDENC_CMD_RC_CFG 0x0005 + #define VIDENC_CMD_DIS_CFG 0x0006 + #define VIDENC_CMD_DIS 0x0007 + #define VIDENC_CMD_INTRA_REFRESH 0x0008 + #define VIDENC_CMD_DIGITAL_ZOOM 0x0009 + + +/* + * Command to pass the frame message information to VIDENC + */ + + +#define VIDENC_CMD_FRAME_START_LEN \ + sizeof(videnc_cmd_frame_start) + +typedef struct { + unsigned short cmd_id; + unsigned short frame_info; + unsigned short frame_rho_budget_word_high; + unsigned short frame_rho_budget_word_low; + unsigned short input_luma_addr_high; + unsigned short input_luma_addr_low; + unsigned short input_chroma_addr_high; + unsigned short input_chroma_addr_low; + unsigned short ref_vop_buf_ptr_high; + unsigned short ref_vop_buf_ptr_low; + unsigned short enc_pkt_buf_ptr_high; + unsigned short enc_pkt_buf_ptr_low; + unsigned short enc_pkt_buf_size_high; + unsigned short enc_pkt_buf_size_low; + unsigned short unfilt_recon_vop_buf_ptr_high; + unsigned short unfilt_recon_vop_buf_ptr_low; + unsigned short filt_recon_vop_buf_ptr_high; + unsigned short filt_recon_vop_buf_ptr_low; +} __attribute__((packed)) videnc_cmd_frame_start; + +/* + * Command to pass the frame-level digital stabilization parameters to VIDENC + */ + + +#define VIDENC_CMD_DIS_LEN \ + sizeof(videnc_cmd_dis) + +typedef struct { + unsigned short cmd_id; + unsigned short vfe_out_prev_luma_addr_high; + unsigned short vfe_out_prev_luma_addr_low; + unsigned short stabilization_info; +} __attribute__((packed)) videnc_cmd_dis; + +/* + * Command to pass the codec related parameters to VIDENC + */ + + +#define VIDENC_CMD_CFG_LEN \ + sizeof(videnc_cmd_cfg) + +typedef struct { + unsigned short cmd_id; + unsigned short cfg_info_0; + unsigned short cfg_info_1; + unsigned short four_mv_threshold; + unsigned short ise_fse_mv_cost_fac; + unsigned short venc_frame_dim; + unsigned short venc_DM_partition; +} __attribute__((packed)) videnc_cmd_cfg; + +/* + * Command to start the video encoding + */ + + +#define VIDENC_CMD_ACTIVE_LEN \ + sizeof(videnc_cmd_active) + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) videnc_cmd_active; + +/* + * Command to stop the video encoding + */ + + +#define VIDENC_CMD_IDLE_LEN \ + sizeof(videnc_cmd_idle) + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) videnc_cmd_idle; + +/* + * Command to query staus of VIDENC + */ + + +#define VIDENC_CMD_STATUS_QUERY_LEN \ + sizeof(videnc_cmd_status_query) + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) videnc_cmd_status_query; + +/* + * Command to set rate control for a frame + */ + + +#define VIDENC_CMD_RC_CFG_LEN \ + sizeof(videnc_cmd_rc_cfg) + +typedef struct { + unsigned short cmd_id; + unsigned short max_frame_qp_delta; + unsigned short max_min_frame_qp; +} __attribute__((packed)) videnc_cmd_rc_cfg; + +/* + * Command to set intra-refreshing + */ + + +#define VIDENC_CMD_INTRA_REFRESH_LEN \ + sizeof(videnc_cmd_intra_refresh) + +typedef struct { + unsigned short cmd_id; + unsigned short num_mb_refresh; + unsigned short mb_index[15]; +} __attribute__((packed)) videnc_cmd_intra_refresh; + +/* + * Command to pass digital zoom information to the VIDENC + */ +#define VIDENC_CMD_DIGITAL_ZOOM_LEN \ + sizeof(videnc_cmd_digital_zoom) + +typedef struct { + unsigned short cmd_id; + unsigned short digital_zoom_en; + unsigned short luma_frame_shift_X; + unsigned short luma_frame_shift_Y; + unsigned short up_ip_luma_rows; + unsigned short up_ip_luma_cols; + unsigned short up_ip_chroma_rows; + unsigned short up_ip_chroma_cols; + unsigned short luma_ph_incr_V_low; + unsigned short luma_ph_incr_V_high; + unsigned short luma_ph_incr_H_low; + unsigned short luma_ph_incr_H_high; + unsigned short chroma_ph_incr_V_low; + unsigned short chroma_ph_incr_V_high; + unsigned short chroma_ph_incr_H_low; + unsigned short chroma_ph_incr_H_high; +} __attribute__((packed)) videnc_cmd_digital_zoom; + +/* + * Command to configure digital stabilization parameters + */ + +#define VIDENC_CMD_DIS_CFG_LEN \ + sizeof(videnc_cmd_dis_cfg) + +typedef struct { + unsigned short cmd_id; + unsigned short image_stab_subf_start_row_col; + unsigned short image_stab_subf_dim; + unsigned short image_stab_info_0; +} __attribute__((packed)) videnc_cmd_dis_cfg; + + +#endif diff --git a/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h new file mode 100644 index 000000000000..55e8fc2269f7 --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h @@ -0,0 +1,910 @@ +#ifndef QDSP5VFECMDI_H +#define QDSP5VFECMDI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + V F E I N T E R N A L C O M M A N D S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are accepted by VFE Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfecmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ +Revision History: + +when who what, where, why +-------- --- ---------------------------------------------------------- +06/12/08 sv initial version +===========================================================================*/ + +/****************************************************************************** + * Commands through vfeCommandScaleQueue + *****************************************************************************/ + +/* + * Command to program scaler for op1 . max op of scaler is VGA + */ + + +#define VFE_CMD_SCALE_OP1_CFG 0x0000 +#define VFE_CMD_SCALE_OP1_CFG_LEN \ + sizeof(vfe_cmd_scale_op1_cfg) + +#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_STANDARD 0x0000 +#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_CASCADED 0x0001 +#define VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_ENA 0x0002 +#define VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_ENA 0x0004 +#define VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_ENA 0x0008 +#define VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_ENA 0x0010 +#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_STANDARD 0x0000 +#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_CASCADED 0x0020 +#define VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_ENA 0x0040 +#define VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_ENA 0x0080 + +#define VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS 0x80000000 +#define VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS 0x80000000 + +typedef struct { + unsigned int cmd_id; + unsigned int scale_op1_sel; + unsigned int y_scaler_cfg_part1; + unsigned int y_scaler_cfg_part2; + unsigned int cbcr_scaler_cfg_part1; + unsigned int cbcr_scaler_cfg_part2; + unsigned int cbcr_scaler_cfg_part3; + unsigned int pp_y_scaler_cfg_part1; + unsigned int pp_y_scaler_cfg_part2; + unsigned int y_scaler_v_coeff_bank_part1[16]; + unsigned int y_scaler_v_coeff_bank_part2[16]; + unsigned int y_scaler_h_coeff_bank_part1[16]; + unsigned int y_scaler_h_coeff_bank_part2[16]; +} __attribute__((packed)) vfe_cmd_scale_op1_cfg; + + +/* + * Command to program scaler for op2 + */ + +#define VFE_CMD_SCALE_OP2_CFG 0x0001 +#define VFE_CMD_SCALE_OP2_CFG_LEN \ + sizeof(vfe_cmd_scale_op2_cfg) + +#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_STANDARD 0x0000 +#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_CASCADED 0x0001 +#define VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_ENA 0x0002 +#define VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_ENA 0x0004 +#define VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_ENA 0x0008 +#define VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_ENA 0x0010 +#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_STANDARD 0x0000 +#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_CASCADED 0x0020 +#define VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_ENA 0x0040 +#define VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_DIS 0x0000 +#define VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_ENA 0x0080 + +#define VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS 0x80000000 +#define VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS 0x80000000 + +typedef struct { + unsigned int cmd_id; + unsigned int scale_op2_sel; + unsigned int y_scaler_cfg_part1; + unsigned int y_scaler_cfg_part2; + unsigned int cbcr_scaler_cfg_part1; + unsigned int cbcr_scaler_cfg_part2; + unsigned int cbcr_scaler_cfg_part3; + unsigned int pp_y_scaler_cfg_part1; + unsigned int pp_y_scaler_cfg_part2; + unsigned int y_scaler_v_coeff_bank_part1[16]; + unsigned int y_scaler_v_coeff_bank_part2[16]; + unsigned int y_scaler_h_coeff_bank_part1[16]; + unsigned int y_scaler_h_coeff_bank_part2[16]; +} __attribute__((packed)) vfe_cmd_scale_op2_cfg; + + +/****************************************************************************** + * Commands through vfeCommandTableQueue + *****************************************************************************/ + +/* + * Command to program the AXI ip paths + */ + +#define VFE_CMD_AXI_IP_CFG 0x0000 +#define VFE_CMD_AXI_IP_CFG_LEN sizeof(vfe_cmd_axi_ip_cfg) + +#define VFE_CMD_IP_SEL_IP_FORMAT_8 0x0000 +#define VFE_CMD_IP_SEL_IP_FORMAT_10 0x0001 +#define VFE_CMD_IP_SEL_IP_FORMAT_12 0x0002 + +typedef struct { + unsigned int cmd_id; + unsigned int ip_sel; + unsigned int ip_cfg_part1; + unsigned int ip_cfg_part2; + unsigned int ip_unpack_cfg_part[6]; + unsigned int ip_buf_addr[8]; +} __attribute__ ((packed)) vfe_cmd_axi_ip_cfg; + + +/* + * Command to program axi op paths + */ + +#define VFE_CMD_AXI_OP_CFG 0x0001 +#define VFE_CMD_AXI_OP_CFG_LEN sizeof(vfe_cmd_axi_op_cfg) + +#define VFE_CMD_OP_SEL_OP1 0x0000 +#define VFE_CMD_OP_SEL_OP2 0x0001 +#define VFE_CMD_OP_SEL_OP1_OP2 0x0002 +#define VFE_CMD_OP_SEL_CTOA 0x0003 +#define VFE_CMD_OP_SEL_CTOA_OP1 0x0004 +#define VFE_CMD_OP_SEL_CTOA_OP2 0x0005 +#define VFE_CMD_OP_SEL_OP_FORMAT_8 0x0000 +#define VFE_CMD_OP_SEL_OP_FORMAT_10 0x0008 +#define VFE_CMD_OP_SEL_OP_FORMAT_12 0x0010 + + +typedef struct { + unsigned int cmd_id; + unsigned int op_sel; + unsigned int op1_y_cfg_part1; + unsigned int op1_y_cfg_part2; + unsigned int op1_cbcr_cfg_part1; + unsigned int op1_cbcr_cfg_part2; + unsigned int op2_y_cfg_part1; + unsigned int op2_y_cfg_part2; + unsigned int op2_cbcr_cfg_part1; + unsigned int op2_cbcr_cfg_part2; + unsigned int op1_buf1_addr[16]; + unsigned int op2_buf1_addr[16]; +} __attribute__((packed)) vfe_cmd_axi_op_cfg; + + + + +/* + * Command to program the roll off correction module + */ + +#define VFE_CMD_ROLLOFF_CFG 0x0002 +#define VFE_CMD_ROLLOFF_CFG_LEN \ + sizeof(vfe_cmd_rolloff_cfg) + + +typedef struct { + unsigned int cmd_id; + unsigned int correction_opt_center_pos; + unsigned int radius_square_entry[32]; + unsigned int red_table_entry[32]; + unsigned int green_table_entry[32]; + unsigned int blue_table_entry[32]; +} __attribute__((packed)) vfe_cmd_rolloff_cfg; + +/* + * Command to program RGB gamma table + */ + +#define VFE_CMD_RGB_GAMMA_CFG 0x0003 +#define VFE_CMD_RGB_GAMMA_CFG_LEN \ + sizeof(vfe_cmd_rgb_gamma_cfg) + +#define VFE_CMD_RGB_GAMMA_SEL_LINEAR 0x0000 +#define VFE_CMD_RGB_GAMMA_SEL_PW_LINEAR 0x0001 +typedef struct { + unsigned int cmd_id; + unsigned int rgb_gamma_sel; + unsigned int rgb_gamma_entry[256]; +} __attribute__((packed)) vfe_cmd_rgb_gamma_cfg; + + +/* + * Command to program luma gamma table for the noise reduction path + */ + +#define VFE_CMD_Y_GAMMA_CFG 0x0004 +#define VFE_CMD_Y_GAMMA_CFG_LEN \ + sizeof(vfe_cmd_y_gamma_cfg) + +#define VFE_CMD_Y_GAMMA_SEL_LINEAR 0x0000 +#define VFE_CMD_Y_GAMMA_SEL_PW_LINEAR 0x0001 + +typedef struct { + unsigned int cmd_id; + unsigned int y_gamma_sel; + unsigned int y_gamma_entry[256]; +} __attribute__((packed)) vfe_cmd_y_gamma_cfg; + + + +/****************************************************************************** + * Commands through vfeCommandQueue + *****************************************************************************/ + +/* + * Command to reset the VFE to a known good state.All previously programmed + * Params will be lost + */ + + +#define VFE_CMD_RESET 0x0000 +#define VFE_CMD_RESET_LEN sizeof(vfe_cmd_reset) + + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) vfe_cmd_reset; + + +/* + * Command to start VFE processing based on the config params + */ + + +#define VFE_CMD_START 0x0001 +#define VFE_CMD_START_LEN sizeof(vfe_cmd_start) + +#define VFE_CMD_STARTUP_PARAMS_SRC_CAMIF 0x0000 +#define VFE_CMD_STARTUP_PARAMS_SRC_AXI 0x0001 +#define VFE_CMD_STARTUP_PARAMS_MODE_CONTINUOUS 0x0000 +#define VFE_CMD_STARTUP_PARAMS_MODE_SNAPSHOT 0x0002 + +#define VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_DIS 0x0000 +#define VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_ENA 0x0001 +#define VFE_CMD_IMAGE_PL_ROLLOFF_CORR_DIS 0x0000 +#define VFE_CMD_IMAGE_PL_ROLLOFF_CORR_ENA 0x0002 +#define VFE_CMD_IMAGE_PL_WHITE_BAL_DIS 0x0000 +#define VFE_CMD_IMAGE_PL_WHITE_BAL_ENA 0x0004 +#define VFE_CMD_IMAGE_PL_RGB_GAMMA_DIS 0x0000 +#define VFE_CMD_IMAGE_PL_RGB_GAMMA_ENA 0x0008 +#define VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_DIS 0x0000 +#define VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_ENA 0x0010 +#define VFE_CMD_IMAGE_PL_ADP_FILTER_DIS 0x0000 +#define VFE_CMD_IMAGE_PL_ADP_FILTER_ENA 0x0020 +#define VFE_CMD_IMAGE_PL_CHROMA_SAMP_DIS 0x0000 +#define VFE_CMD_IMAGE_PL_CHROMA_SAMP_ENA 0x0040 + + +typedef struct { + unsigned int cmd_id; + unsigned int startup_params; + unsigned int image_pipeline; + unsigned int frame_dimension; +} __attribute__((packed)) vfe_cmd_start; + + +/* + * Command to halt all processing + */ + +#define VFE_CMD_STOP 0x0002 +#define VFE_CMD_STOP_LEN sizeof(vfe_cmd_stop) + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) vfe_cmd_stop; + + +/* + * Command to commit the params that have been programmed to take + * effect on the next frame + */ + +#define VFE_CMD_UPDATE 0x0003 +#define VFE_CMD_UPDATE_LEN sizeof(vfe_cmd_update) + + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) vfe_cmd_update; + + +/* + * Command to program CAMIF module + */ + +#define VFE_CMD_CAMIF_CFG 0x0004 +#define VFE_CMD_CAMIF_CFG_LEN sizeof(vfe_cmd_camif_cfg) + +#define VFE_CMD_CFG_VSYNC_SYNC_EDGE_HIGH 0x0000 +#define VFE_CMD_CFG_VSYNC_SYNC_EDGE_LOW 0x0002 +#define VFE_CMD_CFG_HSYNC_SYNC_EDGE_HIGH 0x0000 +#define VFE_CMD_CFG_HSYNC_SYNC_EDGE_LOW 0x0004 +#define VFE_CMD_CFG_SYNC_MODE_APS 0x0000 +#define VFE_CMD_CFG_SYNC_MODE_EFS 0X0008 +#define VFE_CMD_CFG_SYNC_MODE_ELS 0x0010 +#define VFE_CMD_CFG_SYNC_MODE_RVD 0x0018 +#define VFE_CMD_CFG_VFE_SUBSAMP_EN_DIS 0x0000 +#define VFE_CMD_CFG_VFE_SUBSAMP_EN_ENA 0x0020 +#define VFE_CMD_CFG_BUS_SUBSAMP_EN_DIS 0x0000 +#define VFE_CMD_CFG_BUS_SUBSAMP_EN_ENA 0x0080 +#define VFE_CMD_CFG_IRQ_SUBSAMP_EN_DIS 0x0000 +#define VFE_CMD_CFG_IRQ_SUBSAMP_EN_ENA 0x0800 + +#define VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_16 0x0000 +#define VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_12 0x0010 + +#define VFE_CMD_EPOCH_IRQ_1_DIS 0x0000 +#define VFE_CMD_EPOCH_IRQ_1_ENA 0x4000 +#define VFE_CMD_EPOCH_IRQ_2_DIS 0x0000 +#define VFE_CMD_EPOCH_IRQ_2_ENA 0x8000 + +typedef struct { + unsigned int cmd_id; + unsigned int cfg; + unsigned int efs_cfg; + unsigned int frame_cfg; + unsigned int window_width_cfg; + unsigned int window_height_cfg; + unsigned int subsamp1_cfg; + unsigned int subsamp2_cfg; + unsigned int epoch_irq; +} __attribute__((packed)) vfe_cmd_camif_cfg; + + + +/* + * Command to program the black level module + */ + +#define VFE_CMD_BLACK_LVL_CFG 0x0005 +#define VFE_CMD_BLACK_LVL_CFG_LEN sizeof(vfe_cmd_black_lvl_cfg) + +#define VFE_CMD_BL_SEL_MANUAL 0x0000 +#define VFE_CMD_BL_SEL_AUTO 0x0001 + +typedef struct { + unsigned int cmd_id; + unsigned int black_lvl_sel; + unsigned int cfg_part[3]; +} __attribute__((packed)) vfe_cmd_black_lvl_cfg; + + +/* + * Command to program the active region by cropping the region of interest + */ + +#define VFE_CMD_ACTIVE_REGION_CFG 0x0006 +#define VFE_CMD_ACTIVE_REGION_CFG_LEN \ + sizeof(vfe_cmd_active_region_cfg) + + +typedef struct { + unsigned int cmd_id; + unsigned int cfg_part1; + unsigned int cfg_part2; +} __attribute__((packed)) vfe_cmd_active_region_cfg; + + + +/* + * Command to program the defective pixel correction(DPC) , + * adaptive bayer filter (ABF) and demosaic modules + */ + +#define VFE_CMD_DEMOSAIC_CFG 0x0007 +#define VFE_CMD_DEMOSAIC_CFG_LEN sizeof(vfe_cmd_demosaic_cfg) + +#define VFE_CMD_DEMOSAIC_PART1_ABF_EN_DIS 0x0000 +#define VFE_CMD_DEMOSAIC_PART1_ABF_EN_ENA 0x0001 +#define VFE_CMD_DEMOSAIC_PART1_DPC_EN_DIS 0x0000 +#define VFE_CMD_DEMOSAIC_PART1_DPC_EN_ENA 0x0002 +#define VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_OFF 0x0000 +#define VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_ON 0x0004 +#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1 0x00000000 +#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_2 0x10000000 +#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_4 0x20000000 +#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_8 0x30000000 +#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_2 0x50000000 +#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_4 0x60000000 +#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_8 0x70000000 + +typedef struct { + unsigned int cmd_id; + unsigned int demosaic_part1; + unsigned int demosaic_part2; + unsigned int demosaic_part3; + unsigned int demosaic_part4; + unsigned int demosaic_part5; +} __attribute__((packed)) vfe_cmd_demosaic_cfg; + + +/* + * Command to program the ip format + */ + +#define VFE_CMD_IP_FORMAT_CFG 0x0008 +#define VFE_CMD_IP_FORMAT_CFG_LEN \ + sizeof(vfe_cmd_ip_format_cfg) + +#define VFE_CMD_IP_FORMAT_SEL_RGRG 0x0000 +#define VFE_CMD_IP_FORMAT_SEL_GRGR 0x0001 +#define VFE_CMD_IP_FORMAT_SEL_BGBG 0x0002 +#define VFE_CMD_IP_FORMAT_SEL_GBGB 0x0003 +#define VFE_CMD_IP_FORMAT_SEL_YCBYCR 0x0004 +#define VFE_CMD_IP_FORMAT_SEL_YCRYCB 0x0005 +#define VFE_CMD_IP_FORMAT_SEL_CBYCRY 0x0006 +#define VFE_CMD_IP_FORMAT_SEL_CRYCBY 0x0007 +#define VFE_CMD_IP_FORMAT_SEL_NO_CHROMA 0x0000 +#define VFE_CMD_IP_FORMAT_SEL_CHROMA 0x0008 + + +typedef struct { + unsigned int cmd_id; + unsigned int ip_format_sel; + unsigned int balance_gains_part1; + unsigned int balance_gains_part2; +} __attribute__((packed)) vfe_cmd_ip_format_cfg; + + + +/* + * Command to program max and min allowed op values + */ + +#define VFE_CMD_OP_CLAMP_CFG 0x0009 +#define VFE_CMD_OP_CLAMP_CFG_LEN \ + sizeof(vfe_cmd_op_clamp_cfg) + +typedef struct { + unsigned int cmd_id; + unsigned int op_clamp_max; + unsigned int op_clamp_min; +} __attribute__((packed)) vfe_cmd_op_clamp_cfg; + + +/* + * Command to program chroma sub sample module + */ + +#define VFE_CMD_CHROMA_SUBSAMPLE_CFG 0x000A +#define VFE_CMD_CHROMA_SUBSAMPLE_CFG_LEN \ + sizeof(vfe_cmd_chroma_subsample_cfg) + +#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_INTERESTIAL_SAMPS 0x0000 +#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_COSITED_SAMPS 0x0001 +#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_INTERESTIAL_SAMPS 0x0000 +#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_COSITED_SAMPS 0x0002 +#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_DIS 0x0000 +#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_ENA 0x0004 +#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_DIS 0x0000 +#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_ENA 0x0008 + +typedef struct { + unsigned int cmd_id; + unsigned int chroma_subsamp_sel; +} __attribute__((packed)) vfe_cmd_chroma_subsample_cfg; + + +/* + * Command to program the white balance module + */ + +#define VFE_CMD_WHITE_BALANCE_CFG 0x000B +#define VFE_CMD_WHITE_BALANCE_CFG_LEN \ + sizeof(vfe_cmd_white_balance_cfg) + +typedef struct { + unsigned int cmd_id; + unsigned int white_balance_gains; +} __attribute__((packed)) vfe_cmd_white_balance_cfg; + + +/* + * Command to program the color processing module + */ + +#define VFE_CMD_COLOR_PROCESS_CFG 0x000C +#define VFE_CMD_COLOR_PROCESS_CFG_LEN \ + sizeof(vfe_cmd_color_process_cfg) + +#define VFE_CMD_COLOR_CORRE_PART7_Q7_FACTORS 0x0000 +#define VFE_CMD_COLOR_CORRE_PART7_Q8_FACTORS 0x0001 +#define VFE_CMD_COLOR_CORRE_PART7_Q9_FACTORS 0x0002 +#define VFE_CMD_COLOR_CORRE_PART7_Q10_FACTORS 0x0003 + +typedef struct { + unsigned int cmd_id; + unsigned int color_correction_part1; + unsigned int color_correction_part2; + unsigned int color_correction_part3; + unsigned int color_correction_part4; + unsigned int color_correction_part5; + unsigned int color_correction_part6; + unsigned int color_correction_part7; + unsigned int chroma_enhance_part1; + unsigned int chroma_enhance_part2; + unsigned int chroma_enhance_part3; + unsigned int chroma_enhance_part4; + unsigned int chroma_enhance_part5; + unsigned int luma_calc_part1; + unsigned int luma_calc_part2; +} __attribute__((packed)) vfe_cmd_color_process_cfg; + + +/* + * Command to program adaptive filter module + */ + +#define VFE_CMD_ADP_FILTER_CFG 0x000D +#define VFE_CMD_ADP_FILTER_CFG_LEN \ + sizeof(vfe_cmd_adp_filter_cfg) + +#define VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_DIS 0x0000 +#define VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_ENA 0x0001 +#define VFE_CMD_ASF_CFG_PART_NO_SHARP_MODE 0x0000 +#define VFE_CMD_ASF_CFG_PART_SINGLE_FILTER 0x0002 +#define VFE_CMD_ASF_CFG_PART_DUAL_FILTER 0x0004 +#define VFE_CMD_ASF_CFG_PART_SHARP_MODE 0x0007 + +typedef struct { + unsigned int cmd_id; + unsigned int asf_cfg_part[7]; +} __attribute__((packed)) vfe_cmd_adp_filter_cfg; + + +/* + * Command to program for frame skip pattern for op1 and op2 + */ + +#define VFE_CMD_FRAME_SKIP_CFG 0x000E +#define VFE_CMD_FRAME_SKIP_CFG_LEN \ + sizeof(vfe_cmd_frame_skip_cfg) + +typedef struct { + unsigned int cmd_id; + unsigned int frame_skip_pattern_op1; + unsigned int frame_skip_pattern_op2; +} __attribute__((packed)) vfe_cmd_frame_skip_cfg; + + +/* + * Command to program field-of-view crop for digital zoom + */ + +#define VFE_CMD_FOV_CROP 0x000F +#define VFE_CMD_FOV_CROP_LEN sizeof(vfe_cmd_fov_crop) + +typedef struct { + unsigned int cmd_id; + unsigned int fov_crop_part1; + unsigned int fov_crop_part2; +} __attribute__((packed)) vfe_cmd_fov_crop; + + + +/* + * Command to program auto focus(AF) statistics module + */ + +#define VFE_CMD_STATS_AUTOFOCUS_CFG 0x0010 +#define VFE_CMD_STATS_AUTOFOCUS_CFG_LEN \ + sizeof(vfe_cmd_stats_autofocus_cfg) + +#define VFE_CMD_AF_STATS_SEL_STATS_DIS 0x0000 +#define VFE_CMD_AF_STATS_SEL_STATS_ENA 0x0001 +#define VFE_CMD_AF_STATS_SEL_PRI_FIXED 0x0000 +#define VFE_CMD_AF_STATS_SEL_PRI_VAR 0x0002 +#define VFE_CMD_AF_STATS_CFG_PART_METRIC_SUM 0x00000000 +#define VFE_CMD_AF_STATS_CFG_PART_METRIC_MAX 0x00200000 + +typedef struct { + unsigned int cmd_id; + unsigned int af_stats_sel; + unsigned int af_stats_cfg_part[8]; + unsigned int af_stats_op_buf_hdr; + unsigned int af_stats_op_buf[3]; +} __attribute__((packed)) vfe_cmd_stats_autofocus_cfg; + + +/* + * Command to program White balance(wb) and exposure (exp) + * statistics module + */ + +#define VFE_CMD_STATS_WB_EXP_CFG 0x0011 +#define VFE_CMD_STATS_WB_EXP_CFG_LEN \ + sizeof(vfe_cmd_stats_wb_exp_cfg) + +#define VFE_CMD_WB_EXP_STATS_SEL_STATS_DIS 0x0000 +#define VFE_CMD_WB_EXP_STATS_SEL_STATS_ENA 0x0001 +#define VFE_CMD_WB_EXP_STATS_SEL_PRI_FIXED 0x0000 +#define VFE_CMD_WB_EXP_STATS_SEL_PRI_VAR 0x0002 + +#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_8_8 0x0000 +#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_16_16 0x0001 +#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_8_8 0x0000 +#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_4_4 0x0002 + +typedef struct { + unsigned int cmd_id; + unsigned int wb_exp_stats_sel; + unsigned int wb_exp_stats_cfg_part1; + unsigned int wb_exp_stats_cfg_part2; + unsigned int wb_exp_stats_cfg_part3; + unsigned int wb_exp_stats_cfg_part4; + unsigned int wb_exp_stats_op_buf_hdr; + unsigned int wb_exp_stats_op_buf[3]; +} __attribute__((packed)) vfe_cmd_stats_wb_exp_cfg; + + +/* + * Command to program histogram(hg) stats module + */ + +#define VFE_CMD_STATS_HG_CFG 0x0012 +#define VFE_CMD_STATS_HG_CFG_LEN \ + sizeof(vfe_cmd_stats_hg_cfg) + +#define VFE_CMD_HG_STATS_SEL_PRI_FIXED 0x0000 +#define VFE_CMD_HG_STATS_SEL_PRI_VAR 0x0002 + +typedef struct { + unsigned int cmd_id; + unsigned int hg_stats_sel; + unsigned int hg_stats_cfg_part1; + unsigned int hg_stats_cfg_part2; + unsigned int hg_stats_op_buf_hdr; + unsigned int hg_stats_op_buf; +} __attribute__((packed)) vfe_cmd_stats_hg_cfg; + + +/* + * Command to acknowledge last MSG_VFE_OP1 message + */ + +#define VFE_CMD_OP1_ACK 0x0013 +#define VFE_CMD_OP1_ACK_LEN sizeof(vfe_cmd_op1_ack) + +typedef struct { + unsigned int cmd_id; + unsigned int op1_buf_y_addr; + unsigned int op1_buf_cbcr_addr; +} __attribute__((packed)) vfe_cmd_op1_ack; + + + +/* + * Command to acknowledge last MSG_VFE_OP2 message + */ + +#define VFE_CMD_OP2_ACK 0x0014 +#define VFE_CMD_OP2_ACK_LEN sizeof(vfe_cmd_op2_ack) + +typedef struct { + unsigned int cmd_id; + unsigned int op2_buf_y_addr; + unsigned int op2_buf_cbcr_addr; +} __attribute__((packed)) vfe_cmd_op2_ack; + + + +/* + * Command to acknowledge MSG_VFE_STATS_AUTOFOCUS msg + */ + +#define VFE_CMD_STATS_AF_ACK 0x0015 +#define VFE_CMD_STATS_AF_ACK_LEN sizeof(vfe_cmd_stats_af_ack) + + +typedef struct { + unsigned int cmd_id; + unsigned int af_stats_op_buf; +} __attribute__((packed)) vfe_cmd_stats_af_ack; + + +/* + * Command to acknowledge MSG_VFE_STATS_WB_EXP msg + */ + +#define VFE_CMD_STATS_WB_EXP_ACK 0x0016 +#define VFE_CMD_STATS_WB_EXP_ACK_LEN sizeof(vfe_cmd_stats_wb_exp_ack) + +typedef struct { + unsigned int cmd_id; + unsigned int wb_exp_stats_op_buf; +} __attribute__((packed)) vfe_cmd_stats_wb_exp_ack; + + +/* + * Command to acknowledge MSG_VFE_EPOCH1 message + */ + +#define VFE_CMD_EPOCH1_ACK 0x0017 +#define VFE_CMD_EPOCH1_ACK_LEN sizeof(vfe_cmd_epoch1_ack) + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) vfe_cmd_epoch1_ack; + + +/* + * Command to acknowledge MSG_VFE_EPOCH2 message + */ + +#define VFE_CMD_EPOCH2_ACK 0x0018 +#define VFE_CMD_EPOCH2_ACK_LEN sizeof(vfe_cmd_epoch2_ack) + +typedef struct { + unsigned short cmd_id; +} __attribute__((packed)) vfe_cmd_epoch2_ack; + + + +/* + * Command to configure, enable or disable synchronous timer1 + */ + +#define VFE_CMD_SYNC_TIMER1_CFG 0x0019 +#define VFE_CMD_SYNC_TIMER1_CFG_LEN \ + sizeof(vfe_cmd_sync_timer1_cfg) + +#define VFE_CMD_SYNC_T1_CFG_PART1_TIMER_DIS 0x0000 +#define VFE_CMD_SYNC_T1_CFG_PART1_TIMER_ENA 0x0001 +#define VFE_CMD_SYNC_T1_CFG_PART1_POL_HIGH 0x0000 +#define VFE_CMD_SYNC_T1_CFG_PART1_POL_LOW 0x0002 + +typedef struct { + unsigned int cmd_id; + unsigned int sync_t1_cfg_part1; + unsigned int sync_t1_h_sync_countdown; + unsigned int sync_t1_pclk_countdown; + unsigned int sync_t1_duration; +} __attribute__((packed)) vfe_cmd_sync_timer1_cfg; + + +/* + * Command to configure, enable or disable synchronous timer1 + */ + +#define VFE_CMD_SYNC_TIMER2_CFG 0x001A +#define VFE_CMD_SYNC_TIMER2_CFG_LEN \ + sizeof(vfe_cmd_sync_timer2_cfg) + +#define VFE_CMD_SYNC_T2_CFG_PART1_TIMER_DIS 0x0000 +#define VFE_CMD_SYNC_T2_CFG_PART1_TIMER_ENA 0x0001 +#define VFE_CMD_SYNC_T2_CFG_PART1_POL_HIGH 0x0000 +#define VFE_CMD_SYNC_T2_CFG_PART1_POL_LOW 0x0002 + +typedef struct { + unsigned int cmd_id; + unsigned int sync_t2_cfg_part1; + unsigned int sync_t2_h_sync_countdown; + unsigned int sync_t2_pclk_countdown; + unsigned int sync_t2_duration; +} __attribute__((packed)) vfe_cmd_sync_timer2_cfg; + + +/* + * Command to configure and start asynchronous timer1 + */ + +#define VFE_CMD_ASYNC_TIMER1_START 0x001B +#define VFE_CMD_ASYNC_TIMER1_START_LEN \ + sizeof(vfe_cmd_async_timer1_start) + +#define VFE_CMD_ASYNC_T1_POLARITY_A_HIGH 0x0000 +#define VFE_CMD_ASYNC_T1_POLARITY_A_LOW 0x0001 +#define VFE_CMD_ASYNC_T1_POLARITY_B_HIGH 0x0000 +#define VFE_CMD_ASYNC_T1_POLARITY_B_LOW 0x0002 + +typedef struct { + unsigned int cmd_id; + unsigned int async_t1a_cfg; + unsigned int async_t1b_cfg; + unsigned int async_t1_polarity; +} __attribute__((packed)) vfe_cmd_async_timer1_start; + + +/* + * Command to configure and start asynchronous timer2 + */ + +#define VFE_CMD_ASYNC_TIMER2_START 0x001C +#define VFE_CMD_ASYNC_TIMER2_START_LEN \ + sizeof(vfe_cmd_async_timer2_start) + +#define VFE_CMD_ASYNC_T2_POLARITY_A_HIGH 0x0000 +#define VFE_CMD_ASYNC_T2_POLARITY_A_LOW 0x0001 +#define VFE_CMD_ASYNC_T2_POLARITY_B_HIGH 0x0000 +#define VFE_CMD_ASYNC_T2_POLARITY_B_LOW 0x0002 + +typedef struct { + unsigned int cmd_id; + unsigned int async_t2a_cfg; + unsigned int async_t2b_cfg; + unsigned int async_t2_polarity; +} __attribute__((packed)) vfe_cmd_async_timer2_start; + + +/* + * Command to program partial configurations of auto focus(af) + */ + +#define VFE_CMD_STATS_AF_UPDATE 0x001D +#define VFE_CMD_STATS_AF_UPDATE_LEN \ + sizeof(vfe_cmd_stats_af_update) + +#define VFE_CMD_AF_UPDATE_PART1_WINDOW_ONE 0x00000000 +#define VFE_CMD_AF_UPDATE_PART1_WINDOW_MULTI 0x80000000 + +typedef struct { + unsigned int cmd_id; + unsigned int af_update_part1; + unsigned int af_update_part2; +} __attribute__((packed)) vfe_cmd_stats_af_update; + + +/* + * Command to program partial cfg of wb and exp + */ + +#define VFE_CMD_STATS_WB_EXP_UPDATE 0x001E +#define VFE_CMD_STATS_WB_EXP_UPDATE_LEN \ + sizeof(vfe_cmd_stats_wb_exp_update) + +#define VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_8_8 0x0000 +#define VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_16_16 0x0001 +#define VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_8_8 0x0000 +#define VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_4_4 0x0002 + +typedef struct { + unsigned int cmd_id; + unsigned int wb_exp_update_part1; + unsigned int wb_exp_update_part2; + unsigned int wb_exp_update_part3; + unsigned int wb_exp_update_part4; +} __attribute__((packed)) vfe_cmd_stats_wb_exp_update; + + + +/* + * Command to re program the CAMIF FRAME CONFIG settings + */ + +#define VFE_CMD_UPDATE_CAMIF_FRAME_CFG 0x001F +#define VFE_CMD_UPDATE_CAMIF_FRAME_CFG_LEN \ + sizeof(vfe_cmd_update_camif_frame_cfg) + +typedef struct { + unsigned int cmd_id; + unsigned int camif_frame_cfg; +} __attribute__((packed)) vfe_cmd_update_camif_frame_cfg; + + +#endif diff --git a/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h new file mode 100644 index 000000000000..0053cfb65ba1 --- /dev/null +++ b/trunk/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h @@ -0,0 +1,290 @@ +#ifndef QDSP5VFEMSGI_H +#define QDSP5VFEMSGI_H + +/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* + + V F E I N T E R N A L M E S S A G E S + +GENERAL DESCRIPTION + This file contains defintions of format blocks of commands + that are sent by VFE Task + +REFERENCES + None + +EXTERNALIZED FUNCTIONS + None + +Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ +/*=========================================================================== + + EDIT HISTORY FOR FILE + +This section contains comments describing changes made to this file. +Notice that changes are listed in reverse chronological order. + +$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfemsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ +Revision History: + +when who what, where, why +-------- --- ---------------------------------------------------------- +06/12/08 sv initial version +===========================================================================*/ + + +/* + * Message to acknowledge CMD_VFE_REST command + */ + +#define VFE_MSG_RESET_ACK 0x0000 +#define VFE_MSG_RESET_ACK_LEN sizeof(vfe_msg_reset_ack) + +typedef struct { +} __attribute__((packed)) vfe_msg_reset_ack; + + +/* + * Message to acknowledge CMD_VFE_START command + */ + +#define VFE_MSG_START_ACK 0x0001 +#define VFE_MSG_START_ACK_LEN sizeof(vfe_msg_start_ack) + +typedef struct { +} __attribute__((packed)) vfe_msg_start_ack; + +/* + * Message to acknowledge CMD_VFE_STOP command + */ + +#define VFE_MSG_STOP_ACK 0x0002 +#define VFE_MSG_STOP_ACK_LEN sizeof(vfe_msg_stop_ack) + +typedef struct { +} __attribute__((packed)) vfe_msg_stop_ack; + + +/* + * Message to acknowledge CMD_VFE_UPDATE command + */ + +#define VFE_MSG_UPDATE_ACK 0x0003 +#define VFE_MSG_UPDATE_ACK_LEN sizeof(vfe_msg_update_ack) + +typedef struct { +} __attribute__((packed)) vfe_msg_update_ack; + + +/* + * Message to notify the ARM that snapshot processing is complete + * and that the VFE is now STATE_VFE_IDLE + */ + +#define VFE_MSG_SNAPSHOT_DONE 0x0004 +#define VFE_MSG_SNAPSHOT_DONE_LEN \ + sizeof(vfe_msg_snapshot_done) + +typedef struct { +} __attribute__((packed)) vfe_msg_snapshot_done; + + + +/* + * Message to notify ARM that illegal cmd was received and + * system is in the IDLE state + */ + +#define VFE_MSG_ILLEGAL_CMD 0x0005 +#define VFE_MSG_ILLEGAL_CMD_LEN \ + sizeof(vfe_msg_illegal_cmd) + +typedef struct { + unsigned int status; +} __attribute__((packed)) vfe_msg_illegal_cmd; + + +/* + * Message to notify ARM that op1 buf is full and ready + */ + +#define VFE_MSG_OP1 0x0006 +#define VFE_MSG_OP1_LEN sizeof(vfe_msg_op1) + +typedef struct { + unsigned int op1_buf_y_addr; + unsigned int op1_buf_cbcr_addr; + unsigned int black_level_even_col; + unsigned int black_level_odd_col; + unsigned int defect_pixels_detected; + unsigned int asf_max_edge; +} __attribute__((packed)) vfe_msg_op1; + + +/* + * Message to notify ARM that op2 buf is full and ready + */ + +#define VFE_MSG_OP2 0x0007 +#define VFE_MSG_OP2_LEN sizeof(vfe_msg_op2) + +typedef struct { + unsigned int op2_buf_y_addr; + unsigned int op2_buf_cbcr_addr; + unsigned int black_level_even_col; + unsigned int black_level_odd_col; + unsigned int defect_pixels_detected; + unsigned int asf_max_edge; +} __attribute__((packed)) vfe_msg_op2; + + +/* + * Message to notify ARM that autofocus(af) stats are ready + */ + +#define VFE_MSG_STATS_AF 0x0008 +#define VFE_MSG_STATS_AF_LEN sizeof(vfe_msg_stats_af) + +typedef struct { + unsigned int af_stats_op_buffer; +} __attribute__((packed)) vfe_msg_stats_af; + + +/* + * Message to notify ARM that white balance(wb) and exposure (exp) + * stats are ready + */ + +#define VFE_MSG_STATS_WB_EXP 0x0009 +#define VFE_MSG_STATS_WB_EXP_LEN \ + sizeof(vfe_msg_stats_wb_exp) + +typedef struct { + unsigned int wb_exp_stats_op_buf; +} __attribute__((packed)) vfe_msg_stats_wb_exp; + + +/* + * Message to notify the ARM that histogram(hg) stats are ready + */ + +#define VFE_MSG_STATS_HG 0x000A +#define VFE_MSG_STATS_HG_LEN sizeof(vfe_msg_stats_hg) + +typedef struct { + unsigned int hg_stats_op_buf; +} __attribute__((packed)) vfe_msg_stats_hg; + + +/* + * Message to notify the ARM that epoch1 event occurred in the CAMIF + */ + +#define VFE_MSG_EPOCH1 0x000B +#define VFE_MSG_EPOCH1_LEN sizeof(vfe_msg_epoch1) + +typedef struct { +} __attribute__((packed)) vfe_msg_epoch1; + + +/* + * Message to notify the ARM that epoch2 event occurred in the CAMIF + */ + +#define VFE_MSG_EPOCH2 0x000C +#define VFE_MSG_EPOCH2_LEN sizeof(vfe_msg_epoch2) + +typedef struct { +} __attribute__((packed)) vfe_msg_epoch2; + + +/* + * Message to notify the ARM that sync timer1 op is completed + */ + +#define VFE_MSG_SYNC_T1_DONE 0x000D +#define VFE_MSG_SYNC_T1_DONE_LEN sizeof(vfe_msg_sync_t1_done) + +typedef struct { +} __attribute__((packed)) vfe_msg_sync_t1_done; + + +/* + * Message to notify the ARM that sync timer2 op is completed + */ + +#define VFE_MSG_SYNC_T2_DONE 0x000E +#define VFE_MSG_SYNC_T2_DONE_LEN sizeof(vfe_msg_sync_t2_done) + +typedef struct { +} __attribute__((packed)) vfe_msg_sync_t2_done; + + +/* + * Message to notify the ARM that async t1 operation completed + */ + +#define VFE_MSG_ASYNC_T1_DONE 0x000F +#define VFE_MSG_ASYNC_T1_DONE_LEN sizeof(vfe_msg_async_t1_done) + +typedef struct { +} __attribute__((packed)) vfe_msg_async_t1_done; + + + +/* + * Message to notify the ARM that async t2 operation completed + */ + +#define VFE_MSG_ASYNC_T2_DONE 0x0010 +#define VFE_MSG_ASYNC_T2_DONE_LEN sizeof(vfe_msg_async_t2_done) + +typedef struct { +} __attribute__((packed)) vfe_msg_async_t2_done; + + + +/* + * Message to notify the ARM that an error has occurred + */ + +#define VFE_MSG_ERROR 0x0011 +#define VFE_MSG_ERROR_LEN sizeof(vfe_msg_error) + +#define VFE_MSG_ERR_COND_NO_CAMIF_ERR 0x0000 +#define VFE_MSG_ERR_COND_CAMIF_ERR 0x0001 +#define VFE_MSG_ERR_COND_OP1_Y_NO_BUS_OF 0x0000 +#define VFE_MSG_ERR_COND_OP1_Y_BUS_OF 0x0002 +#define VFE_MSG_ERR_COND_OP1_CBCR_NO_BUS_OF 0x0000 +#define VFE_MSG_ERR_COND_OP1_CBCR_BUS_OF 0x0004 +#define VFE_MSG_ERR_COND_OP2_Y_NO_BUS_OF 0x0000 +#define VFE_MSG_ERR_COND_OP2_Y_BUS_OF 0x0008 +#define VFE_MSG_ERR_COND_OP2_CBCR_NO_BUS_OF 0x0000 +#define VFE_MSG_ERR_COND_OP2_CBCR_BUS_OF 0x0010 +#define VFE_MSG_ERR_COND_AF_NO_BUS_OF 0x0000 +#define VFE_MSG_ERR_COND_AF_BUS_OF 0x0020 +#define VFE_MSG_ERR_COND_WB_EXP_NO_BUS_OF 0x0000 +#define VFE_MSG_ERR_COND_WB_EXP_BUS_OF 0x0040 +#define VFE_MSG_ERR_COND_NO_AXI_ERR 0x0000 +#define VFE_MSG_ERR_COND_AXI_ERR 0x0080 + +#define VFE_MSG_CAMIF_STS_IDLE 0x0000 +#define VFE_MSG_CAMIF_STS_CAPTURE_DATA 0x0001 + +typedef struct { + unsigned int err_cond; + unsigned int camif_sts; +} __attribute__((packed)) vfe_msg_error; + + +#endif diff --git a/trunk/drivers/staging/dream/include/media/msm_camera.h b/trunk/drivers/staging/dream/include/media/msm_camera.h new file mode 100644 index 000000000000..09812d62cc1e --- /dev/null +++ b/trunk/drivers/staging/dream/include/media/msm_camera.h @@ -0,0 +1,388 @@ +/* + * Copyright (C) 2008-2009 QUALCOMM Incorporated. + */ +#ifndef __LINUX_MSM_CAMERA_H +#define __LINUX_MSM_CAMERA_H + +#include +#include +#include + +#define MSM_CAM_IOCTL_MAGIC 'm' + +#define MSM_CAM_IOCTL_GET_SENSOR_INFO \ + _IOR(MSM_CAM_IOCTL_MAGIC, 1, struct msm_camsensor_info *) + +#define MSM_CAM_IOCTL_REGISTER_PMEM \ + _IOW(MSM_CAM_IOCTL_MAGIC, 2, struct msm_pmem_info *) + +#define MSM_CAM_IOCTL_UNREGISTER_PMEM \ + _IOW(MSM_CAM_IOCTL_MAGIC, 3, unsigned) + +#define MSM_CAM_IOCTL_CTRL_COMMAND \ + _IOW(MSM_CAM_IOCTL_MAGIC, 4, struct msm_ctrl_cmd *) + +#define MSM_CAM_IOCTL_CONFIG_VFE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 5, struct msm_camera_vfe_cfg_cmd *) + +#define MSM_CAM_IOCTL_GET_STATS \ + _IOR(MSM_CAM_IOCTL_MAGIC, 6, struct msm_camera_stats_event_ctrl *) + +#define MSM_CAM_IOCTL_GETFRAME \ + _IOR(MSM_CAM_IOCTL_MAGIC, 7, struct msm_camera_get_frame *) + +#define MSM_CAM_IOCTL_ENABLE_VFE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 8, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_CTRL_CMD_DONE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 9, struct camera_cmd *) + +#define MSM_CAM_IOCTL_CONFIG_CMD \ + _IOW(MSM_CAM_IOCTL_MAGIC, 10, struct camera_cmd *) + +#define MSM_CAM_IOCTL_DISABLE_VFE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 11, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_PAD_REG_RESET2 \ + _IOW(MSM_CAM_IOCTL_MAGIC, 12, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_VFE_APPS_RESET \ + _IOW(MSM_CAM_IOCTL_MAGIC, 13, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER \ + _IOW(MSM_CAM_IOCTL_MAGIC, 14, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_RELEASE_STATS_BUFFER \ + _IOW(MSM_CAM_IOCTL_MAGIC, 15, struct msm_stats_buf *) + +#define MSM_CAM_IOCTL_AXI_CONFIG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 16, struct msm_camera_vfe_cfg_cmd *) + +#define MSM_CAM_IOCTL_GET_PICTURE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 17, struct msm_camera_ctrl_cmd *) + +#define MSM_CAM_IOCTL_SET_CROP \ + _IOW(MSM_CAM_IOCTL_MAGIC, 18, struct crop_info *) + +#define MSM_CAM_IOCTL_PICT_PP \ + _IOW(MSM_CAM_IOCTL_MAGIC, 19, uint8_t *) + +#define MSM_CAM_IOCTL_PICT_PP_DONE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 20, struct msm_snapshot_pp_status *) + +#define MSM_CAM_IOCTL_SENSOR_IO_CFG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 21, struct sensor_cfg_data *) + +#define MSM_CAMERA_LED_OFF 0 +#define MSM_CAMERA_LED_LOW 1 +#define MSM_CAMERA_LED_HIGH 2 + +#define MSM_CAM_IOCTL_FLASH_LED_CFG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 22, unsigned *) + +#define MSM_CAM_IOCTL_UNBLOCK_POLL_FRAME \ + _IO(MSM_CAM_IOCTL_MAGIC, 23) + +#define MSM_CAM_IOCTL_CTRL_COMMAND_2 \ + _IOW(MSM_CAM_IOCTL_MAGIC, 24, struct msm_ctrl_cmd *) + +#define MAX_SENSOR_NUM 3 +#define MAX_SENSOR_NAME 32 + +#define MSM_CAM_CTRL_CMD_DONE 0 +#define MSM_CAM_SENSOR_VFE_CMD 1 + +/***************************************************** + * structure + *****************************************************/ + +/* define five type of structures for userspace <==> kernel + * space communication: + * command 1 - 2 are from userspace ==> kernel + * command 3 - 4 are from kernel ==> userspace + * + * 1. control command: control command(from control thread), + * control status (from config thread); + */ +struct msm_ctrl_cmd { + uint16_t type; + uint16_t length; + void *value; + uint16_t status; + uint32_t timeout_ms; + int resp_fd; /* FIXME: to be used by the kernel, pass-through for now */ +}; + +struct msm_vfe_evt_msg { + unsigned short type; /* 1 == event (RPC), 0 == message (adsp) */ + unsigned short msg_id; + unsigned int len; /* size in, number of bytes out */ + void *data; +}; + +#define MSM_CAM_RESP_CTRL 0 +#define MSM_CAM_RESP_STAT_EVT_MSG 1 +#define MSM_CAM_RESP_V4L2 2 +#define MSM_CAM_RESP_MAX 3 + +/* this one is used to send ctrl/status up to config thread */ +struct msm_stats_event_ctrl { + /* 0 - ctrl_cmd from control thread, + * 1 - stats/event kernel, + * 2 - V4L control or read request */ + int resptype; + int timeout_ms; + struct msm_ctrl_cmd ctrl_cmd; + /* struct vfe_event_t stats_event; */ + struct msm_vfe_evt_msg stats_event; +}; + +/* 2. config command: config command(from config thread); */ +struct msm_camera_cfg_cmd { + /* what to config: + * 1 - sensor config, 2 - vfe config */ + uint16_t cfg_type; + + /* sensor config type */ + uint16_t cmd_type; + uint16_t queue; + uint16_t length; + void *value; +}; + +#define CMD_GENERAL 0 +#define CMD_AXI_CFG_OUT1 1 +#define CMD_AXI_CFG_SNAP_O1_AND_O2 2 +#define CMD_AXI_CFG_OUT2 3 +#define CMD_PICT_T_AXI_CFG 4 +#define CMD_PICT_M_AXI_CFG 5 +#define CMD_RAW_PICT_AXI_CFG 6 +#define CMD_STATS_AXI_CFG 7 +#define CMD_STATS_AF_AXI_CFG 8 +#define CMD_FRAME_BUF_RELEASE 9 +#define CMD_PREV_BUF_CFG 10 +#define CMD_SNAP_BUF_RELEASE 11 +#define CMD_SNAP_BUF_CFG 12 +#define CMD_STATS_DISABLE 13 +#define CMD_STATS_ENABLE 14 +#define CMD_STATS_AF_ENABLE 15 +#define CMD_STATS_BUF_RELEASE 16 +#define CMD_STATS_AF_BUF_RELEASE 17 +#define UPDATE_STATS_INVALID 18 + +/* vfe config command: config command(from config thread)*/ +struct msm_vfe_cfg_cmd { + int cmd_type; + uint16_t length; + void *value; +}; + +#define MAX_CAMERA_ENABLE_NAME_LEN 32 +struct camera_enable_cmd { + char name[MAX_CAMERA_ENABLE_NAME_LEN]; +}; + +#define MSM_PMEM_OUTPUT1 0 +#define MSM_PMEM_OUTPUT2 1 +#define MSM_PMEM_OUTPUT1_OUTPUT2 2 +#define MSM_PMEM_THUMBAIL 3 +#define MSM_PMEM_MAINIMG 4 +#define MSM_PMEM_RAW_MAINIMG 5 +#define MSM_PMEM_AEC_AWB 6 +#define MSM_PMEM_AF 7 +#define MSM_PMEM_MAX 8 + +#define FRAME_PREVIEW_OUTPUT1 0 +#define FRAME_PREVIEW_OUTPUT2 1 +#define FRAME_SNAPSHOT 2 +#define FRAME_THUMBAIL 3 +#define FRAME_RAW_SNAPSHOT 4 +#define FRAME_MAX 5 + +struct msm_pmem_info { + int type; + int fd; + void *vaddr; + uint32_t y_off; + uint32_t cbcr_off; + uint8_t active; +}; + +struct outputCfg { + uint32_t height; + uint32_t width; + + uint32_t window_height_firstline; + uint32_t window_height_lastline; +}; + +#define OUTPUT_1 0 +#define OUTPUT_2 1 +#define OUTPUT_1_AND_2 2 +#define CAMIF_TO_AXI_VIA_OUTPUT_2 3 +#define OUTPUT_1_AND_CAMIF_TO_AXI_VIA_OUTPUT_2 4 +#define OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 5 +#define LAST_AXI_OUTPUT_MODE_ENUM = OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 6 + +#define MSM_FRAME_PREV_1 0 +#define MSM_FRAME_PREV_2 1 +#define MSM_FRAME_ENC 2 + +struct msm_frame { + int path; + unsigned long buffer; + uint32_t y_off; + uint32_t cbcr_off; + int fd; + + void *cropinfo; + int croplen; +}; + +#define STAT_AEAW 0 +#define STAT_AF 1 +#define STAT_MAX 2 + +struct msm_stats_buf { + int type; + unsigned long buffer; + int fd; +}; + +#define MSM_V4L2_VID_CAP_TYPE 0 +#define MSM_V4L2_STREAM_ON 1 +#define MSM_V4L2_STREAM_OFF 2 +#define MSM_V4L2_SNAPSHOT 3 +#define MSM_V4L2_QUERY_CTRL 4 +#define MSM_V4L2_GET_CTRL 5 +#define MSM_V4L2_SET_CTRL 6 +#define MSM_V4L2_QUERY 7 +#define MSM_V4L2_MAX 8 + +struct crop_info { + void *info; + int len; +}; + +struct msm_postproc { + int ftnum; + struct msm_frame fthumnail; + int fmnum; + struct msm_frame fmain; +}; + +struct msm_snapshot_pp_status { + void *status; +}; + +#define CFG_SET_MODE 0 +#define CFG_SET_EFFECT 1 +#define CFG_START 2 +#define CFG_PWR_UP 3 +#define CFG_PWR_DOWN 4 +#define CFG_WRITE_EXPOSURE_GAIN 5 +#define CFG_SET_DEFAULT_FOCUS 6 +#define CFG_MOVE_FOCUS 7 +#define CFG_REGISTER_TO_REAL_GAIN 8 +#define CFG_REAL_TO_REGISTER_GAIN 9 +#define CFG_SET_FPS 10 +#define CFG_SET_PICT_FPS 11 +#define CFG_SET_BRIGHTNESS 12 +#define CFG_SET_CONTRAST 13 +#define CFG_SET_ZOOM 14 +#define CFG_SET_EXPOSURE_MODE 15 +#define CFG_SET_WB 16 +#define CFG_SET_ANTIBANDING 17 +#define CFG_SET_EXP_GAIN 18 +#define CFG_SET_PICT_EXP_GAIN 19 +#define CFG_SET_LENS_SHADING 20 +#define CFG_GET_PICT_FPS 21 +#define CFG_GET_PREV_L_PF 22 +#define CFG_GET_PREV_P_PL 23 +#define CFG_GET_PICT_L_PF 24 +#define CFG_GET_PICT_P_PL 25 +#define CFG_GET_AF_MAX_STEPS 26 +#define CFG_GET_PICT_MAX_EXP_LC 27 +#define CFG_MAX 28 + +#define MOVE_NEAR 0 +#define MOVE_FAR 1 + +#define SENSOR_PREVIEW_MODE 0 +#define SENSOR_SNAPSHOT_MODE 1 +#define SENSOR_RAW_SNAPSHOT_MODE 2 + +#define SENSOR_QTR_SIZE 0 +#define SENSOR_FULL_SIZE 1 +#define SENSOR_INVALID_SIZE 2 + +#define CAMERA_EFFECT_OFF 0 +#define CAMERA_EFFECT_MONO 1 +#define CAMERA_EFFECT_NEGATIVE 2 +#define CAMERA_EFFECT_SOLARIZE 3 +#define CAMERA_EFFECT_PASTEL 4 +#define CAMERA_EFFECT_MOSAIC 5 +#define CAMERA_EFFECT_RESIZE 6 +#define CAMERA_EFFECT_SEPIA 7 +#define CAMERA_EFFECT_POSTERIZE 8 +#define CAMERA_EFFECT_WHITEBOARD 9 +#define CAMERA_EFFECT_BLACKBOARD 10 +#define CAMERA_EFFECT_AQUA 11 +#define CAMERA_EFFECT_MAX 12 + +struct sensor_pict_fps { + uint16_t prevfps; + uint16_t pictfps; +}; + +struct exp_gain_cfg { + uint16_t gain; + uint32_t line; +}; + +struct focus_cfg { + int32_t steps; + int dir; +}; + +struct fps_cfg { + uint16_t f_mult; + uint16_t fps_div; + uint32_t pict_fps_div; +}; + +struct sensor_cfg_data { + int cfgtype; + int mode; + int rs; + uint8_t max_steps; + + union { + int8_t effect; + uint8_t lens_shading; + uint16_t prevl_pf; + uint16_t prevp_pl; + uint16_t pictl_pf; + uint16_t pictp_pl; + uint32_t pict_max_exp_lc; + uint16_t p_fps; + struct sensor_pict_fps gfps; + struct exp_gain_cfg exp_gain; + struct focus_cfg focus; + struct fps_cfg fps; + } cfg; +}; + +#define GET_NAME 0 +#define GET_PREVIEW_LINE_PER_FRAME 1 +#define GET_PREVIEW_PIXELS_PER_LINE 2 +#define GET_SNAPSHOT_LINE_PER_FRAME 3 +#define GET_SNAPSHOT_PIXELS_PER_LINE 4 +#define GET_SNAPSHOT_FPS 5 +#define GET_SNAPSHOT_MAX_EP_LINE_CNT 6 + +struct msm_camsensor_info { + char name[MAX_SENSOR_NAME]; + uint8_t flash_enabled; +}; +#endif /* __LINUX_MSM_CAMERA_H */ diff --git a/trunk/drivers/staging/dream/pmem.c b/trunk/drivers/staging/dream/pmem.c new file mode 100644 index 000000000000..4d3d300bb736 --- /dev/null +++ b/trunk/drivers/staging/dream/pmem.c @@ -0,0 +1,1333 @@ +/* drivers/android/pmem.c + * + * Copyright (C) 2007 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PMEM_MAX_DEVICES 10 +#define PMEM_MAX_ORDER 128 +#define PMEM_MIN_ALLOC PAGE_SIZE + +#define PMEM_DEBUG 1 + +/* indicates that a refernce to this file has been taken via get_pmem_file, + * the file should not be released until put_pmem_file is called */ +#define PMEM_FLAGS_BUSY 0x1 +/* indicates that this is a suballocation of a larger master range */ +#define PMEM_FLAGS_CONNECTED (0x1 << 1) +/* indicates this is a master and not a sub allocation and that it is mmaped */ +#define PMEM_FLAGS_MASTERMAP (0x1 << 2) +/* submap and unsubmap flags indicate: + * 00: subregion has never been mmaped + * 10: subregion has been mmaped, reference to the mm was taken + * 11: subretion has ben released, refernece to the mm still held + * 01: subretion has been released, reference to the mm has been released + */ +#define PMEM_FLAGS_SUBMAP (0x1 << 3) +#define PMEM_FLAGS_UNSUBMAP (0x1 << 4) + + +struct pmem_data { + /* in alloc mode: an index into the bitmap + * in no_alloc mode: the size of the allocation */ + int index; + /* see flags above for descriptions */ + unsigned int flags; + /* protects this data field, if the mm_mmap sem will be held at the + * same time as this sem, the mm sem must be taken first (as this is + * the order for vma_open and vma_close ops */ + struct rw_semaphore sem; + /* info about the mmaping process */ + struct vm_area_struct *vma; + /* task struct of the mapping process */ + struct task_struct *task; + /* process id of teh mapping process */ + pid_t pid; + /* file descriptor of the master */ + int master_fd; + /* file struct of the master */ + struct file *master_file; + /* a list of currently available regions if this is a suballocation */ + struct list_head region_list; + /* a linked list of data so we can access them for debugging */ + struct list_head list; +#if PMEM_DEBUG + int ref; +#endif +}; + +struct pmem_bits { + unsigned allocated:1; /* 1 if allocated, 0 if free */ + unsigned order:7; /* size of the region in pmem space */ +}; + +struct pmem_region_node { + struct pmem_region region; + struct list_head list; +}; + +#define PMEM_DEBUG_MSGS 0 +#if PMEM_DEBUG_MSGS +#define DLOG(fmt, args...) \ + do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \ + ##args); } \ + while (0) +#else +#define DLOG(x...) do {} while (0) +#endif + +struct pmem_info { + struct miscdevice dev; + /* physical start address of the remaped pmem space */ + unsigned long base; + /* vitual start address of the remaped pmem space */ + unsigned char __iomem *vbase; + /* total size of the pmem space */ + unsigned long size; + /* number of entries in the pmem space */ + unsigned long num_entries; + /* pfn of the garbage page in memory */ + unsigned long garbage_pfn; + /* index of the garbage page in the pmem space */ + int garbage_index; + /* the bitmap for the region indicating which entries are allocated + * and which are free */ + struct pmem_bits *bitmap; + /* indicates the region should not be managed with an allocator */ + unsigned no_allocator; + /* indicates maps of this region should be cached, if a mix of + * cached and uncached is desired, set this and open the device with + * O_SYNC to get an uncached region */ + unsigned cached; + unsigned buffered; + /* in no_allocator mode the first mapper gets the whole space and sets + * this flag */ + unsigned allocated; + /* for debugging, creates a list of pmem file structs, the + * data_list_sem should be taken before pmem_data->sem if both are + * needed */ + struct semaphore data_list_sem; + struct list_head data_list; + /* pmem_sem protects the bitmap array + * a write lock should be held when modifying entries in bitmap + * a read lock should be held when reading data from bits or + * dereferencing a pointer into bitmap + * + * pmem_data->sem protects the pmem data of a particular file + * Many of the function that require the pmem_data->sem have a non- + * locking version for when the caller is already holding that sem. + * + * IF YOU TAKE BOTH LOCKS TAKE THEM IN THIS ORDER: + * down(pmem_data->sem) => down(bitmap_sem) + */ + struct rw_semaphore bitmap_sem; + + long (*ioctl)(struct file *, unsigned int, unsigned long); + int (*release)(struct inode *, struct file *); +}; + +static struct pmem_info pmem[PMEM_MAX_DEVICES]; +static int id_count; + +#define PMEM_IS_FREE(id, index) (!(pmem[id].bitmap[index].allocated)) +#define PMEM_ORDER(id, index) pmem[id].bitmap[index].order +#define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index))) +#define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index))) +#define PMEM_OFFSET(index) (index * PMEM_MIN_ALLOC) +#define PMEM_START_ADDR(id, index) (PMEM_OFFSET(index) + pmem[id].base) +#define PMEM_LEN(id, index) ((1 << PMEM_ORDER(id, index)) * PMEM_MIN_ALLOC) +#define PMEM_END_ADDR(id, index) (PMEM_START_ADDR(id, index) + \ + PMEM_LEN(id, index)) +#define PMEM_START_VADDR(id, index) (PMEM_OFFSET(id, index) + pmem[id].vbase) +#define PMEM_END_VADDR(id, index) (PMEM_START_VADDR(id, index) + \ + PMEM_LEN(id, index)) +#define PMEM_REVOKED(data) (data->flags & PMEM_FLAGS_REVOKED) +#define PMEM_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK))) +#define PMEM_IS_SUBMAP(data) ((data->flags & PMEM_FLAGS_SUBMAP) && \ + (!(data->flags & PMEM_FLAGS_UNSUBMAP))) + +static int pmem_release(struct inode *, struct file *); +static int pmem_mmap(struct file *, struct vm_area_struct *); +static int pmem_open(struct inode *, struct file *); +static long pmem_ioctl(struct file *, unsigned int, unsigned long); + +const struct file_operations pmem_fops = { + .release = pmem_release, + .mmap = pmem_mmap, + .open = pmem_open, + .unlocked_ioctl = pmem_ioctl, + .llseek = noop_llseek, +}; + +static int get_id(struct file *file) +{ + return MINOR(file->f_dentry->d_inode->i_rdev); +} + +static int is_pmem_file(struct file *file) +{ + int id; + + if (unlikely(!file || !file->f_dentry || !file->f_dentry->d_inode)) + return 0; + id = get_id(file); + if (unlikely(id >= PMEM_MAX_DEVICES)) + return 0; + if (unlikely(file->f_dentry->d_inode->i_rdev != + MKDEV(MISC_MAJOR, pmem[id].dev.minor))) + return 0; + return 1; +} + +static int has_allocation(struct file *file) +{ + struct pmem_data *data; + /* check is_pmem_file first if not accessed via pmem_file_ops */ + + if (unlikely(!file->private_data)) + return 0; + data = file->private_data; + if (unlikely(data->index < 0)) + return 0; + return 1; +} + +static int is_master_owner(struct file *file) +{ + struct file *master_file; + struct pmem_data *data; + int put_needed, ret = 0; + + if (!is_pmem_file(file) || !has_allocation(file)) + return 0; + data = file->private_data; + if (PMEM_FLAGS_MASTERMAP & data->flags) + return 1; + master_file = fget_light(data->master_fd, &put_needed); + if (master_file && data->master_file == master_file) + ret = 1; + fput_light(master_file, put_needed); + return ret; +} + +static int pmem_free(int id, int index) +{ + /* caller should hold the write lock on pmem_sem! */ + int buddy, curr = index; + DLOG("index %d\n", index); + + if (pmem[id].no_allocator) { + pmem[id].allocated = 0; + return 0; + } + /* clean up the bitmap, merging any buddies */ + pmem[id].bitmap[curr].allocated = 0; + /* find a slots buddy Buddy# = Slot# ^ (1 << order) + * if the buddy is also free merge them + * repeat until the buddy is not free or end of the bitmap is reached + */ + do { + buddy = PMEM_BUDDY_INDEX(id, curr); + if (PMEM_IS_FREE(id, buddy) && + PMEM_ORDER(id, buddy) == PMEM_ORDER(id, curr)) { + PMEM_ORDER(id, buddy)++; + PMEM_ORDER(id, curr)++; + curr = min(buddy, curr); + } else { + break; + } + } while (curr < pmem[id].num_entries); + + return 0; +} + +static void pmem_revoke(struct file *file, struct pmem_data *data); + +static int pmem_release(struct inode *inode, struct file *file) +{ + struct pmem_data *data = file->private_data; + struct pmem_region_node *region_node; + struct list_head *elt, *elt2; + int id = get_id(file), ret = 0; + + + down(&pmem[id].data_list_sem); + /* if this file is a master, revoke all the memory in the connected + * files */ + if (PMEM_FLAGS_MASTERMAP & data->flags) { + struct pmem_data *sub_data; + list_for_each(elt, &pmem[id].data_list) { + sub_data = list_entry(elt, struct pmem_data, list); + down_read(&sub_data->sem); + if (PMEM_IS_SUBMAP(sub_data) && + file == sub_data->master_file) { + up_read(&sub_data->sem); + pmem_revoke(file, sub_data); + } else + up_read(&sub_data->sem); + } + } + list_del(&data->list); + up(&pmem[id].data_list_sem); + + + down_write(&data->sem); + + /* if its not a conencted file and it has an allocation, free it */ + if (!(PMEM_FLAGS_CONNECTED & data->flags) && has_allocation(file)) { + down_write(&pmem[id].bitmap_sem); + ret = pmem_free(id, data->index); + up_write(&pmem[id].bitmap_sem); + } + + /* if this file is a submap (mapped, connected file), downref the + * task struct */ + if (PMEM_FLAGS_SUBMAP & data->flags) + if (data->task) { + put_task_struct(data->task); + data->task = NULL; + } + + file->private_data = NULL; + + list_for_each_safe(elt, elt2, &data->region_list) { + region_node = list_entry(elt, struct pmem_region_node, list); + list_del(elt); + kfree(region_node); + } + BUG_ON(!list_empty(&data->region_list)); + + up_write(&data->sem); + kfree(data); + if (pmem[id].release) + ret = pmem[id].release(inode, file); + + return ret; +} + +static int pmem_open(struct inode *inode, struct file *file) +{ + struct pmem_data *data; + int id = get_id(file); + int ret = 0; + + DLOG("current %u file %p(%d)\n", current->pid, file, file_count(file)); + /* setup file->private_data to indicate its unmapped */ + /* you can only open a pmem device one time */ + if (file->private_data != NULL) + return -1; + data = kmalloc(sizeof(struct pmem_data), GFP_KERNEL); + if (!data) { + printk("pmem: unable to allocate memory for pmem metadata."); + return -1; + } + data->flags = 0; + data->index = -1; + data->task = NULL; + data->vma = NULL; + data->pid = 0; + data->master_file = NULL; +#if PMEM_DEBUG + data->ref = 0; +#endif + INIT_LIST_HEAD(&data->region_list); + init_rwsem(&data->sem); + + file->private_data = data; + INIT_LIST_HEAD(&data->list); + + down(&pmem[id].data_list_sem); + list_add(&data->list, &pmem[id].data_list); + up(&pmem[id].data_list_sem); + return ret; +} + +static unsigned long pmem_order(unsigned long len) +{ + int i; + + len = (len + PMEM_MIN_ALLOC - 1)/PMEM_MIN_ALLOC; + len--; + for (i = 0; i < sizeof(len)*8; i++) + if (len >> i == 0) + break; + return i; +} + +static int pmem_allocate(int id, unsigned long len) +{ + /* caller should hold the write lock on pmem_sem! */ + /* return the corresponding pdata[] entry */ + int curr = 0; + int end = pmem[id].num_entries; + int best_fit = -1; + unsigned long order = pmem_order(len); + + if (pmem[id].no_allocator) { + DLOG("no allocator"); + if ((len > pmem[id].size) || pmem[id].allocated) + return -1; + pmem[id].allocated = 1; + return len; + } + + if (order > PMEM_MAX_ORDER) + return -1; + DLOG("order %lx\n", order); + + /* look through the bitmap: + * if you find a free slot of the correct order use it + * otherwise, use the best fit (smallest with size > order) slot + */ + while (curr < end) { + if (PMEM_IS_FREE(id, curr)) { + if (PMEM_ORDER(id, curr) == (unsigned char)order) { + /* set the not free bit and clear others */ + best_fit = curr; + break; + } + if (PMEM_ORDER(id, curr) > (unsigned char)order && + (best_fit < 0 || + PMEM_ORDER(id, curr) < PMEM_ORDER(id, best_fit))) + best_fit = curr; + } + curr = PMEM_NEXT_INDEX(id, curr); + } + + /* if best_fit < 0, there are no suitable slots, + * return an error + */ + if (best_fit < 0) { + printk("pmem: no space left to allocate!\n"); + return -1; + } + + /* now partition the best fit: + * split the slot into 2 buddies of order - 1 + * repeat until the slot is of the correct order + */ + while (PMEM_ORDER(id, best_fit) > (unsigned char)order) { + int buddy; + PMEM_ORDER(id, best_fit) -= 1; + buddy = PMEM_BUDDY_INDEX(id, best_fit); + PMEM_ORDER(id, buddy) = PMEM_ORDER(id, best_fit); + } + pmem[id].bitmap[best_fit].allocated = 1; + return best_fit; +} + +static pgprot_t phys_mem_access_prot(struct file *file, pgprot_t vma_prot) +{ + int id = get_id(file); +#ifdef pgprot_noncached + if (pmem[id].cached == 0 || file->f_flags & O_SYNC) + return pgprot_noncached(vma_prot); +#endif +#ifdef pgprot_ext_buffered + else if (pmem[id].buffered) + return pgprot_ext_buffered(vma_prot); +#endif + return vma_prot; +} + +static unsigned long pmem_start_addr(int id, struct pmem_data *data) +{ + if (pmem[id].no_allocator) + return PMEM_START_ADDR(id, 0); + else + return PMEM_START_ADDR(id, data->index); + +} + +static void *pmem_start_vaddr(int id, struct pmem_data *data) +{ + return pmem_start_addr(id, data) - pmem[id].base + pmem[id].vbase; +} + +static unsigned long pmem_len(int id, struct pmem_data *data) +{ + if (pmem[id].no_allocator) + return data->index; + else + return PMEM_LEN(id, data->index); +} + +static int pmem_map_garbage(int id, struct vm_area_struct *vma, + struct pmem_data *data, unsigned long offset, + unsigned long len) +{ + int i, garbage_pages = len >> PAGE_SHIFT; + + vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP | VM_SHARED | VM_WRITE; + for (i = 0; i < garbage_pages; i++) { + if (vm_insert_pfn(vma, vma->vm_start + offset + (i * PAGE_SIZE), + pmem[id].garbage_pfn)) + return -EAGAIN; + } + return 0; +} + +static int pmem_unmap_pfn_range(int id, struct vm_area_struct *vma, + struct pmem_data *data, unsigned long offset, + unsigned long len) +{ + int garbage_pages; + DLOG("unmap offset %lx len %lx\n", offset, len); + + BUG_ON(!PMEM_IS_PAGE_ALIGNED(len)); + + garbage_pages = len >> PAGE_SHIFT; + zap_page_range(vma, vma->vm_start + offset, len, NULL); + pmem_map_garbage(id, vma, data, offset, len); + return 0; +} + +static int pmem_map_pfn_range(int id, struct vm_area_struct *vma, + struct pmem_data *data, unsigned long offset, + unsigned long len) +{ + DLOG("map offset %lx len %lx\n", offset, len); + BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_start)); + BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_end)); + BUG_ON(!PMEM_IS_PAGE_ALIGNED(len)); + BUG_ON(!PMEM_IS_PAGE_ALIGNED(offset)); + + if (io_remap_pfn_range(vma, vma->vm_start + offset, + (pmem_start_addr(id, data) + offset) >> PAGE_SHIFT, + len, vma->vm_page_prot)) { + return -EAGAIN; + } + return 0; +} + +static int pmem_remap_pfn_range(int id, struct vm_area_struct *vma, + struct pmem_data *data, unsigned long offset, + unsigned long len) +{ + /* hold the mm semp for the vma you are modifying when you call this */ + BUG_ON(!vma); + zap_page_range(vma, vma->vm_start + offset, len, NULL); + return pmem_map_pfn_range(id, vma, data, offset, len); +} + +static void pmem_vma_open(struct vm_area_struct *vma) +{ + struct file *file = vma->vm_file; + struct pmem_data *data = file->private_data; + int id = get_id(file); + /* this should never be called as we don't support copying pmem + * ranges via fork */ + BUG_ON(!has_allocation(file)); + down_write(&data->sem); + /* remap the garbage pages, forkers don't get access to the data */ + pmem_unmap_pfn_range(id, vma, data, 0, vma->vm_start - vma->vm_end); + up_write(&data->sem); +} + +static void pmem_vma_close(struct vm_area_struct *vma) +{ + struct file *file = vma->vm_file; + struct pmem_data *data = file->private_data; + + DLOG("current %u ppid %u file %p count %d\n", current->pid, + current->parent->pid, file, file_count(file)); + if (unlikely(!is_pmem_file(file) || !has_allocation(file))) { + printk(KERN_WARNING "pmem: something is very wrong, you are " + "closing a vm backing an allocation that doesn't " + "exist!\n"); + return; + } + down_write(&data->sem); + if (data->vma == vma) { + data->vma = NULL; + if ((data->flags & PMEM_FLAGS_CONNECTED) && + (data->flags & PMEM_FLAGS_SUBMAP)) + data->flags |= PMEM_FLAGS_UNSUBMAP; + } + /* the kernel is going to free this vma now anyway */ + up_write(&data->sem); +} + +static struct vm_operations_struct vm_ops = { + .open = pmem_vma_open, + .close = pmem_vma_close, +}; + +static int pmem_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct pmem_data *data; + int index; + unsigned long vma_size = vma->vm_end - vma->vm_start; + int ret = 0, id = get_id(file); + + if (vma->vm_pgoff || !PMEM_IS_PAGE_ALIGNED(vma_size)) { +#if PMEM_DEBUG + printk(KERN_ERR "pmem: mmaps must be at offset zero, aligned" + " and a multiple of pages_size.\n"); +#endif + return -EINVAL; + } + + data = file->private_data; + down_write(&data->sem); + /* check this file isn't already mmaped, for submaps check this file + * has never been mmaped */ + if ((data->flags & PMEM_FLAGS_MASTERMAP) || + (data->flags & PMEM_FLAGS_SUBMAP) || + (data->flags & PMEM_FLAGS_UNSUBMAP)) { +#if PMEM_DEBUG + printk(KERN_ERR "pmem: you can only mmap a pmem file once, " + "this file is already mmaped. %x\n", data->flags); +#endif + ret = -EINVAL; + goto error; + } + /* if file->private_data == unalloced, alloc*/ + if (data && data->index == -1) { + down_write(&pmem[id].bitmap_sem); + index = pmem_allocate(id, vma->vm_end - vma->vm_start); + up_write(&pmem[id].bitmap_sem); + data->index = index; + } + /* either no space was available or an error occured */ + if (!has_allocation(file)) { + ret = -EINVAL; + printk("pmem: could not find allocation for map.\n"); + goto error; + } + + if (pmem_len(id, data) < vma_size) { +#if PMEM_DEBUG + printk(KERN_WARNING "pmem: mmap size [%lu] does not match" + "size of backing region [%lu].\n", vma_size, + pmem_len(id, data)); +#endif + ret = -EINVAL; + goto error; + } + + vma->vm_pgoff = pmem_start_addr(id, data) >> PAGE_SHIFT; + vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_page_prot); + + if (data->flags & PMEM_FLAGS_CONNECTED) { + struct pmem_region_node *region_node; + struct list_head *elt; + if (pmem_map_garbage(id, vma, data, 0, vma_size)) { + printk("pmem: mmap failed in kernel!\n"); + ret = -EAGAIN; + goto error; + } + list_for_each(elt, &data->region_list) { + region_node = list_entry(elt, struct pmem_region_node, + list); + DLOG("remapping file: %p %lx %lx\n", file, + region_node->region.offset, + region_node->region.len); + if (pmem_remap_pfn_range(id, vma, data, + region_node->region.offset, + region_node->region.len)) { + ret = -EAGAIN; + goto error; + } + } + data->flags |= PMEM_FLAGS_SUBMAP; + get_task_struct(current->group_leader); + data->task = current->group_leader; + data->vma = vma; +#if PMEM_DEBUG + data->pid = current->pid; +#endif + DLOG("submmapped file %p vma %p pid %u\n", file, vma, + current->pid); + } else { + if (pmem_map_pfn_range(id, vma, data, 0, vma_size)) { + printk(KERN_INFO "pmem: mmap failed in kernel!\n"); + ret = -EAGAIN; + goto error; + } + data->flags |= PMEM_FLAGS_MASTERMAP; + data->pid = current->pid; + } + vma->vm_ops = &vm_ops; +error: + up_write(&data->sem); + return ret; +} + +/* the following are the api for accessing pmem regions by other drivers + * from inside the kernel */ +int get_pmem_user_addr(struct file *file, unsigned long *start, + unsigned long *len) +{ + struct pmem_data *data; + if (!is_pmem_file(file) || !has_allocation(file)) { +#if PMEM_DEBUG + printk(KERN_INFO "pmem: requested pmem data from invalid" + "file.\n"); +#endif + return -1; + } + data = file->private_data; + down_read(&data->sem); + if (data->vma) { + *start = data->vma->vm_start; + *len = data->vma->vm_end - data->vma->vm_start; + } else { + *start = 0; + *len = 0; + } + up_read(&data->sem); + return 0; +} + +int get_pmem_addr(struct file *file, unsigned long *start, + unsigned long *vstart, unsigned long *len) +{ + struct pmem_data *data; + int id; + + if (!is_pmem_file(file) || !has_allocation(file)) + return -1; + + data = file->private_data; + if (data->index == -1) { +#if PMEM_DEBUG + printk(KERN_INFO "pmem: requested pmem data from file with no " + "allocation.\n"); + return -1; +#endif + } + id = get_id(file); + + down_read(&data->sem); + *start = pmem_start_addr(id, data); + *len = pmem_len(id, data); + *vstart = (unsigned long)pmem_start_vaddr(id, data); + up_read(&data->sem); +#if PMEM_DEBUG + down_write(&data->sem); + data->ref++; + up_write(&data->sem); +#endif + return 0; +} + +int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart, + unsigned long *len, struct file **filp) +{ + struct file *file; + + file = fget(fd); + if (unlikely(file == NULL)) { + printk(KERN_INFO "pmem: requested data from file descriptor " + "that doesn't exist."); + return -1; + } + + if (get_pmem_addr(file, start, vstart, len)) + goto end; + + if (filp) + *filp = file; + return 0; +end: + fput(file); + return -1; +} + +void put_pmem_file(struct file *file) +{ + struct pmem_data *data; + int id; + + if (!is_pmem_file(file)) + return; + id = get_id(file); + data = file->private_data; +#if PMEM_DEBUG + down_write(&data->sem); + if (data->ref == 0) { + printk("pmem: pmem_put > pmem_get %s (pid %d)\n", + pmem[id].dev.name, data->pid); + BUG(); + } + data->ref--; + up_write(&data->sem); +#endif + fput(file); +} + +void flush_pmem_file(struct file *file, unsigned long offset, unsigned long len) +{ + struct pmem_data *data; + int id; + void *vaddr; + struct pmem_region_node *region_node; + struct list_head *elt; + void *flush_start, *flush_end; + + if (!is_pmem_file(file) || !has_allocation(file)) + return; + + id = get_id(file); + data = file->private_data; + if (!pmem[id].cached) + return; + + down_read(&data->sem); + vaddr = pmem_start_vaddr(id, data); + /* if this isn't a submmapped file, flush the whole thing */ + if (unlikely(!(data->flags & PMEM_FLAGS_CONNECTED))) { + dmac_flush_range(vaddr, vaddr + pmem_len(id, data)); + goto end; + } + /* otherwise, flush the region of the file we are drawing */ + list_for_each(elt, &data->region_list) { + region_node = list_entry(elt, struct pmem_region_node, list); + if ((offset >= region_node->region.offset) && + ((offset + len) <= (region_node->region.offset + + region_node->region.len))) { + flush_start = vaddr + region_node->region.offset; + flush_end = flush_start + region_node->region.len; + dmac_flush_range(flush_start, flush_end); + break; + } + } +end: + up_read(&data->sem); +} + +static int pmem_connect(unsigned long connect, struct file *file) +{ + struct pmem_data *data = file->private_data; + struct pmem_data *src_data; + struct file *src_file; + int ret = 0, put_needed; + + down_write(&data->sem); + /* retrieve the src file and check it is a pmem file with an alloc */ + src_file = fget_light(connect, &put_needed); + DLOG("connect %p to %p\n", file, src_file); + if (!src_file) { + printk(KERN_INFO "pmem: src file not found!\n"); + ret = -EINVAL; + goto err_no_file; + } + if (unlikely(!is_pmem_file(src_file) || !has_allocation(src_file))) { + printk(KERN_INFO "pmem: src file is not a pmem file or has no " + "alloc!\n"); + ret = -EINVAL; + goto err_bad_file; + } + src_data = src_file->private_data; + + if (has_allocation(file) && (data->index != src_data->index)) { + printk(KERN_INFO "pmem: file is already mapped but doesn't " + "match this src_file!\n"); + ret = -EINVAL; + goto err_bad_file; + } + data->index = src_data->index; + data->flags |= PMEM_FLAGS_CONNECTED; + data->master_fd = connect; + data->master_file = src_file; + +err_bad_file: + fput_light(src_file, put_needed); +err_no_file: + up_write(&data->sem); + return ret; +} + +static void pmem_unlock_data_and_mm(struct pmem_data *data, + struct mm_struct *mm) +{ + up_write(&data->sem); + if (mm != NULL) { + up_write(&mm->mmap_sem); + mmput(mm); + } +} + +static int pmem_lock_data_and_mm(struct file *file, struct pmem_data *data, + struct mm_struct **locked_mm) +{ + int ret = 0; + struct mm_struct *mm = NULL; + *locked_mm = NULL; +lock_mm: + down_read(&data->sem); + if (PMEM_IS_SUBMAP(data)) { + mm = get_task_mm(data->task); + if (!mm) { +#if PMEM_DEBUG + printk(KERN_DEBUG "pmem: can't remap task is gone!\n"); +#endif + up_read(&data->sem); + return -1; + } + } + up_read(&data->sem); + + if (mm) + down_write(&mm->mmap_sem); + + down_write(&data->sem); + /* check that the file didn't get mmaped before we could take the + * data sem, this should be safe b/c you can only submap each file + * once */ + if (PMEM_IS_SUBMAP(data) && !mm) { + pmem_unlock_data_and_mm(data, mm); + up_write(&data->sem); + goto lock_mm; + } + /* now check that vma.mm is still there, it could have been + * deleted by vma_close before we could get the data->sem */ + if ((data->flags & PMEM_FLAGS_UNSUBMAP) && (mm != NULL)) { + /* might as well release this */ + if (data->flags & PMEM_FLAGS_SUBMAP) { + put_task_struct(data->task); + data->task = NULL; + /* lower the submap flag to show the mm is gone */ + data->flags &= ~(PMEM_FLAGS_SUBMAP); + } + pmem_unlock_data_and_mm(data, mm); + return -1; + } + *locked_mm = mm; + return ret; +} + +int pmem_remap(struct pmem_region *region, struct file *file, + unsigned operation) +{ + int ret; + struct pmem_region_node *region_node; + struct mm_struct *mm = NULL; + struct list_head *elt, *elt2; + int id = get_id(file); + struct pmem_data *data = file->private_data; + + /* pmem region must be aligned on a page boundry */ + if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) || + !PMEM_IS_PAGE_ALIGNED(region->len))) { +#if PMEM_DEBUG + printk(KERN_DEBUG "pmem: request for unaligned pmem " + "suballocation %lx %lx\n", region->offset, region->len); +#endif + return -EINVAL; + } + + /* if userspace requests a region of len 0, there's nothing to do */ + if (region->len == 0) + return 0; + + /* lock the mm and data */ + ret = pmem_lock_data_and_mm(file, data, &mm); + if (ret) + return 0; + + /* only the owner of the master file can remap the client fds + * that back in it */ + if (!is_master_owner(file)) { +#if PMEM_DEBUG + printk("pmem: remap requested from non-master process\n"); +#endif + ret = -EINVAL; + goto err; + } + + /* check that the requested range is within the src allocation */ + if (unlikely((region->offset > pmem_len(id, data)) || + (region->len > pmem_len(id, data)) || + (region->offset + region->len > pmem_len(id, data)))) { +#if PMEM_DEBUG + printk(KERN_INFO "pmem: suballoc doesn't fit in src_file!\n"); +#endif + ret = -EINVAL; + goto err; + } + + if (operation == PMEM_MAP) { + region_node = kmalloc(sizeof(struct pmem_region_node), + GFP_KERNEL); + if (!region_node) { + ret = -ENOMEM; +#if PMEM_DEBUG + printk(KERN_INFO "No space to allocate metadata!"); +#endif + goto err; + } + region_node->region = *region; + list_add(®ion_node->list, &data->region_list); + } else if (operation == PMEM_UNMAP) { + int found = 0; + list_for_each_safe(elt, elt2, &data->region_list) { + region_node = list_entry(elt, struct pmem_region_node, + list); + if (region->len == 0 || + (region_node->region.offset == region->offset && + region_node->region.len == region->len)) { + list_del(elt); + kfree(region_node); + found = 1; + } + } + if (!found) { +#if PMEM_DEBUG + printk("pmem: Unmap region does not map any mapped " + "region!"); +#endif + ret = -EINVAL; + goto err; + } + } + + if (data->vma && PMEM_IS_SUBMAP(data)) { + if (operation == PMEM_MAP) + ret = pmem_remap_pfn_range(id, data->vma, data, + region->offset, region->len); + else if (operation == PMEM_UNMAP) + ret = pmem_unmap_pfn_range(id, data->vma, data, + region->offset, region->len); + } + +err: + pmem_unlock_data_and_mm(data, mm); + return ret; +} + +static void pmem_revoke(struct file *file, struct pmem_data *data) +{ + struct pmem_region_node *region_node; + struct list_head *elt, *elt2; + struct mm_struct *mm = NULL; + int id = get_id(file); + int ret = 0; + + data->master_file = NULL; + ret = pmem_lock_data_and_mm(file, data, &mm); + /* if lock_data_and_mm fails either the task that mapped the fd, or + * the vma that mapped it have already gone away, nothing more + * needs to be done */ + if (ret) + return; + /* unmap everything */ + /* delete the regions and region list nothing is mapped any more */ + if (data->vma) + list_for_each_safe(elt, elt2, &data->region_list) { + region_node = list_entry(elt, struct pmem_region_node, + list); + pmem_unmap_pfn_range(id, data->vma, data, + region_node->region.offset, + region_node->region.len); + list_del(elt); + kfree(region_node); + } + /* delete the master file */ + pmem_unlock_data_and_mm(data, mm); +} + +static void pmem_get_size(struct pmem_region *region, struct file *file) +{ + struct pmem_data *data = file->private_data; + int id = get_id(file); + + if (!has_allocation(file)) { + region->offset = 0; + region->len = 0; + return; + } else { + region->offset = pmem_start_addr(id, data); + region->len = pmem_len(id, data); + } + DLOG("offset %lx len %lx\n", region->offset, region->len); +} + + +static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct pmem_data *data; + int id = get_id(file); + + switch (cmd) { + case PMEM_GET_PHYS: + { + struct pmem_region region; + DLOG("get_phys\n"); + if (!has_allocation(file)) { + region.offset = 0; + region.len = 0; + } else { + data = file->private_data; + region.offset = pmem_start_addr(id, data); + region.len = pmem_len(id, data); + } + printk(KERN_INFO "pmem: request for physical address " + "of pmem region from process %d.\n", current->pid); + if (copy_to_user((void __user *)arg, ®ion, + sizeof(struct pmem_region))) + return -EFAULT; + break; + } + case PMEM_MAP: + { + struct pmem_region region; + if (copy_from_user(®ion, (void __user *)arg, + sizeof(struct pmem_region))) + return -EFAULT; + data = file->private_data; + return pmem_remap(®ion, file, PMEM_MAP); + } + break; + case PMEM_UNMAP: + { + struct pmem_region region; + if (copy_from_user(®ion, (void __user *)arg, + sizeof(struct pmem_region))) + return -EFAULT; + data = file->private_data; + return pmem_remap(®ion, file, PMEM_UNMAP); + break; + } + case PMEM_GET_SIZE: + { + struct pmem_region region; + DLOG("get_size\n"); + pmem_get_size(®ion, file); + if (copy_to_user((void __user *)arg, ®ion, + sizeof(struct pmem_region))) + return -EFAULT; + break; + } + case PMEM_GET_TOTAL_SIZE: + { + struct pmem_region region; + DLOG("get total size\n"); + region.offset = 0; + get_id(file); + region.len = pmem[id].size; + if (copy_to_user((void __user *)arg, ®ion, + sizeof(struct pmem_region))) + return -EFAULT; + break; + } + case PMEM_ALLOCATE: + { + if (has_allocation(file)) + return -EINVAL; + data = file->private_data; + data->index = pmem_allocate(id, arg); + break; + } + case PMEM_CONNECT: + DLOG("connect\n"); + return pmem_connect(arg, file); + break; + default: + if (pmem[id].ioctl) + return pmem[id].ioctl(file, cmd, arg); + return -EINVAL; + } + return 0; +} + +#if PMEM_DEBUG +static ssize_t debug_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static ssize_t debug_read(struct file *file, char __user *buf, size_t count, + loff_t *ppos) +{ + struct list_head *elt, *elt2; + struct pmem_data *data; + struct pmem_region_node *region_node; + int id = (int)file->private_data; + const int debug_bufmax = 4096; + static char buffer[4096]; + int n = 0; + + DLOG("debug open\n"); + n = scnprintf(buffer, debug_bufmax, + "pid #: mapped regions (offset, len) (offset,len)...\n"); + + down(&pmem[id].data_list_sem); + list_for_each(elt, &pmem[id].data_list) { + data = list_entry(elt, struct pmem_data, list); + down_read(&data->sem); + n += scnprintf(buffer + n, debug_bufmax - n, "pid %u:", + data->pid); + list_for_each(elt2, &data->region_list) { + region_node = list_entry(elt2, struct pmem_region_node, + list); + n += scnprintf(buffer + n, debug_bufmax - n, + "(%lx,%lx) ", + region_node->region.offset, + region_node->region.len); + } + n += scnprintf(buffer + n, debug_bufmax - n, "\n"); + up_read(&data->sem); + } + up(&pmem[id].data_list_sem); + + n++; + buffer[n] = 0; + return simple_read_from_buffer(buf, count, ppos, buffer, n); +} + +static struct file_operations debug_fops = { + .read = debug_read, + .open = debug_open, + .llseek = default_llseek, +}; +#endif + +#if 0 +static struct miscdevice pmem_dev = { + .name = "pmem", + .fops = &pmem_fops, +}; +#endif + +int pmem_setup(struct android_pmem_platform_data *pdata, + long (*ioctl)(struct file *, unsigned int, unsigned long), + int (*release)(struct inode *, struct file *)) +{ + int err = 0; + int i, index = 0; + int id = id_count; + id_count++; + + pmem[id].no_allocator = pdata->no_allocator; + pmem[id].cached = pdata->cached; + pmem[id].buffered = pdata->buffered; + pmem[id].base = pdata->start; + pmem[id].size = pdata->size; + pmem[id].ioctl = ioctl; + pmem[id].release = release; + init_rwsem(&pmem[id].bitmap_sem); + sema_init(&pmem[id].data_list_sem, 1); + INIT_LIST_HEAD(&pmem[id].data_list); + pmem[id].dev.name = pdata->name; + pmem[id].dev.minor = id; + pmem[id].dev.fops = &pmem_fops; + printk(KERN_INFO "%s: %d init\n", pdata->name, pdata->cached); + + err = misc_register(&pmem[id].dev); + if (err) { + printk(KERN_ALERT "Unable to register pmem driver!\n"); + goto err_cant_register_device; + } + pmem[id].num_entries = pmem[id].size / PMEM_MIN_ALLOC; + + pmem[id].bitmap = kcalloc(pmem[id].num_entries, + sizeof(struct pmem_bits), GFP_KERNEL); + if (!pmem[id].bitmap) + goto err_no_mem_for_metadata; + + for (i = sizeof(pmem[id].num_entries) * 8 - 1; i >= 0; i--) { + if ((pmem[id].num_entries) & 1<name, S_IFREG | S_IRUGO, NULL, (void *)id, + &debug_fops); +#endif + return 0; +error_cant_remap: + kfree(pmem[id].bitmap); +err_no_mem_for_metadata: + misc_deregister(&pmem[id].dev); +err_cant_register_device: + return -1; +} + +static int pmem_probe(struct platform_device *pdev) +{ + struct android_pmem_platform_data *pdata; + + if (!pdev || !pdev->dev.platform_data) { + printk(KERN_ALERT "Unable to probe pmem!\n"); + return -1; + } + pdata = pdev->dev.platform_data; + return pmem_setup(pdata, NULL, NULL); +} + + +static int pmem_remove(struct platform_device *pdev) +{ + int id = pdev->id; + __free_page(pfn_to_page(pmem[id].garbage_pfn)); + misc_deregister(&pmem[id].dev); + return 0; +} + +static struct platform_driver pmem_driver = { + .probe = pmem_probe, + .remove = pmem_remove, + .driver = { .name = "android_pmem" } +}; + + +static int __init pmem_init(void) +{ + return platform_driver_register(&pmem_driver); +} + +static void __exit pmem_exit(void) +{ + platform_driver_unregister(&pmem_driver); +} + +module_init(pmem_init); +module_exit(pmem_exit); + diff --git a/trunk/drivers/staging/dream/qdsp5/Makefile b/trunk/drivers/staging/dream/qdsp5/Makefile new file mode 100644 index 000000000000..44ae6b4b47ec --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/Makefile @@ -0,0 +1,18 @@ +ccflags-y:=-Idrivers/staging/dream/include +obj-y += adsp.o +ifeq ($(CONFIG_MSM_AMSS_VERSION_6350),y) +obj-y += adsp_info.o +obj-y += audio_evrc.o audio_qcelp.o audio_amrnb.o audio_aac.o +else +obj-y += adsp_6225.o +endif + +obj-y += adsp_driver.o +obj-y += adsp_video_verify_cmd.o +obj-y += adsp_videoenc_verify_cmd.o +obj-y += adsp_jpeg_verify_cmd.o adsp_jpeg_patch_event.o +obj-y += adsp_vfe_verify_cmd.o adsp_vfe_patch_event.o +obj-y += adsp_lpm_verify_cmd.o +obj-y += audio_out.o audio_in.o audio_mp3.o audmgr.o audpp.o +obj-y += snd.o + diff --git a/trunk/drivers/staging/dream/qdsp5/adsp.c b/trunk/drivers/staging/dream/qdsp5/adsp.c new file mode 100644 index 000000000000..f1e9d81674e8 --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/adsp.c @@ -0,0 +1,1159 @@ +/* arch/arm/mach-msm/qdsp5/adsp.c + * + * Register/Interrupt access for userspace aDSP library. + * + * Copyright (c) 2008 QUALCOMM Incorporated + * Copyright (C) 2008 Google, Inc. + * Author: Iliyan Malchev + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +/* TODO: + * - move shareable rpc code outside of adsp.c + * - general solution for virt->phys patchup + * - queue IDs should be relative to modules + * - disallow access to non-associated queues + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static inline void prevent_suspend(void) +{ +} +static inline void allow_suspend(void) +{ +} + +#include +#include +#include "adsp.h" + +#define INT_ADSP INT_ADSP_A9_A11 + +static struct adsp_info adsp_info; +static struct msm_rpc_endpoint *rpc_cb_server_client; +static struct msm_adsp_module *adsp_modules; +static int adsp_open_count; +static DEFINE_MUTEX(adsp_open_lock); + +/* protect interactions with the ADSP command/message queue */ +static spinlock_t adsp_cmd_lock; + +static uint32_t current_image = -1; + +void adsp_set_image(struct adsp_info *info, uint32_t image) +{ + current_image = image; +} + +/* + * Checks whether the module_id is available in the + * module_entries table.If module_id is available returns `0`. + * If module_id is not available returns `-ENXIO`. + */ +#if CONFIG_MSM_AMSS_VERSION >= 6350 +static int32_t adsp_validate_module(uint32_t module_id) +{ + uint32_t *ptr; + uint32_t module_index; + uint32_t num_mod_entries; + + ptr = adsp_info.init_info_ptr->module_entries; + num_mod_entries = adsp_info.init_info_ptr->module_table_size; + + for (module_index = 0; module_index < num_mod_entries; module_index++) + if (module_id == ptr[module_index]) + return 0; + + return -ENXIO; +} +#else +static inline int32_t adsp_validate_module(uint32_t module_id) { return 0; } +#endif + +uint32_t adsp_get_module(struct adsp_info *info, uint32_t task) +{ + BUG_ON(current_image == -1UL); + return info->task_to_module[current_image][task]; +} + +uint32_t adsp_get_queue_offset(struct adsp_info *info, uint32_t queue_id) +{ + BUG_ON(current_image == -1UL); + return info->queue_offset[current_image][queue_id]; +} + +static int rpc_adsp_rtos_app_to_modem(uint32_t cmd, uint32_t module, + struct msm_adsp_module *adsp_module) +{ + int rc; + struct rpc_adsp_rtos_app_to_modem_args_t rpc_req; + struct rpc_reply_hdr *rpc_rsp; + + msm_rpc_setup_req(&rpc_req.hdr, + RPC_ADSP_RTOS_ATOM_PROG, + msm_rpc_get_vers(adsp_module->rpc_client), + RPC_ADSP_RTOS_APP_TO_MODEM_PROC); + + rpc_req.gotit = cpu_to_be32(1); + rpc_req.cmd = cpu_to_be32(cmd); + rpc_req.proc_id = cpu_to_be32(RPC_ADSP_RTOS_PROC_APPS); + rpc_req.module = cpu_to_be32(module); + rc = msm_rpc_write(adsp_module->rpc_client, &rpc_req, sizeof(rpc_req)); + if (rc < 0) { + pr_err("adsp: could not send RPC request: %d\n", rc); + return rc; + } + + rc = msm_rpc_read(adsp_module->rpc_client, + (void **)&rpc_rsp, -1, (5*HZ)); + if (rc < 0) { + pr_err("adsp: error receiving RPC reply: %d (%d)\n", + rc, -ERESTARTSYS); + return rc; + } + + if (be32_to_cpu(rpc_rsp->reply_stat) != RPCMSG_REPLYSTAT_ACCEPTED) { + pr_err("adsp: RPC call was denied!\n"); + kfree(rpc_rsp); + return -EPERM; + } + + if (be32_to_cpu(rpc_rsp->data.acc_hdr.accept_stat) != + RPC_ACCEPTSTAT_SUCCESS) { + pr_err("adsp error: RPC call was not successful (%d)\n", + be32_to_cpu(rpc_rsp->data.acc_hdr.accept_stat)); + kfree(rpc_rsp); + return -EINVAL; + } + + kfree(rpc_rsp); + return 0; +} + +#if CONFIG_MSM_AMSS_VERSION >= 6350 +static int get_module_index(uint32_t id) +{ + int mod_idx; + for (mod_idx = 0; mod_idx < adsp_info.module_count; mod_idx++) + if (adsp_info.module[mod_idx].id == id) + return mod_idx; + + return -ENXIO; +} +#endif + +static struct msm_adsp_module *find_adsp_module_by_id( + struct adsp_info *info, uint32_t id) +{ + if (id > info->max_module_id) { + return NULL; + } else { +#if CONFIG_MSM_AMSS_VERSION >= 6350 + id = get_module_index(id); + if (id < 0) + return NULL; +#endif + return info->id_to_module[id]; + } +} + +static struct msm_adsp_module *find_adsp_module_by_name( + struct adsp_info *info, const char *name) +{ + unsigned n; + for (n = 0; n < info->module_count; n++) + if (!strcmp(name, adsp_modules[n].name)) + return adsp_modules + n; + return NULL; +} + +static int adsp_rpc_init(struct msm_adsp_module *adsp_module) +{ + /* remove the original connect once compatible support is complete */ + adsp_module->rpc_client = msm_rpc_connect( + RPC_ADSP_RTOS_ATOM_PROG, + RPC_ADSP_RTOS_ATOM_VERS, + MSM_RPC_UNINTERRUPTIBLE); + + if (IS_ERR(adsp_module->rpc_client)) { + int rc = PTR_ERR(adsp_module->rpc_client); + adsp_module->rpc_client = 0; + pr_err("adsp: could not open rpc client: %d\n", rc); + return rc; + } + + return 0; +} + +#if CONFIG_MSM_AMSS_VERSION >= 6350 +/* + * Send RPC_ADSP_RTOS_CMD_GET_INIT_INFO cmd to ARM9 and get + * queue offsets and module entries (init info) as part of the event. + */ +static void msm_get_init_info(void) +{ + int rc; + struct rpc_adsp_rtos_app_to_modem_args_t rpc_req; + + adsp_info.init_info_rpc_client = msm_rpc_connect( + RPC_ADSP_RTOS_ATOM_PROG, + RPC_ADSP_RTOS_ATOM_VERS, + MSM_RPC_UNINTERRUPTIBLE); + if (IS_ERR(adsp_info.init_info_rpc_client)) { + rc = PTR_ERR(adsp_info.init_info_rpc_client); + adsp_info.init_info_rpc_client = 0; + pr_err("adsp: could not open rpc client: %d\n", rc); + return; + } + + msm_rpc_setup_req(&rpc_req.hdr, + RPC_ADSP_RTOS_ATOM_PROG, + msm_rpc_get_vers(adsp_info.init_info_rpc_client), + RPC_ADSP_RTOS_APP_TO_MODEM_PROC); + + rpc_req.gotit = cpu_to_be32(1); + rpc_req.cmd = cpu_to_be32(RPC_ADSP_RTOS_CMD_GET_INIT_INFO); + rpc_req.proc_id = cpu_to_be32(RPC_ADSP_RTOS_PROC_APPS); + rpc_req.module = 0; + + rc = msm_rpc_write(adsp_info.init_info_rpc_client, + &rpc_req, sizeof(rpc_req)); + if (rc < 0) + pr_err("adsp: could not send RPC request: %d\n", rc); +} +#endif + +int msm_adsp_get(const char *name, struct msm_adsp_module **out, + struct msm_adsp_ops *ops, void *driver_data) +{ + struct msm_adsp_module *module; + int rc = 0; + +#if CONFIG_MSM_AMSS_VERSION >= 6350 + static uint32_t init_info_cmd_sent; + if (!init_info_cmd_sent) { + msm_get_init_info(); + init_waitqueue_head(&adsp_info.init_info_wait); + rc = wait_event_timeout(adsp_info.init_info_wait, + adsp_info.init_info_state == ADSP_STATE_INIT_INFO, + 5 * HZ); + if (!rc) { + pr_info("adsp: INIT_INFO failed\n"); + return -ETIMEDOUT; + } + init_info_cmd_sent++; + } +#endif + + module = find_adsp_module_by_name(&adsp_info, name); + if (!module) + return -ENODEV; + + mutex_lock(&module->lock); + pr_info("adsp: opening module %s\n", module->name); + if (module->open_count++ == 0 && module->clk) + clk_enable(module->clk); + + mutex_lock(&adsp_open_lock); + if (adsp_open_count++ == 0) { + enable_irq(INT_ADSP); + prevent_suspend(); + } + mutex_unlock(&adsp_open_lock); + + if (module->ops) { + rc = -EBUSY; + goto done; + } + + rc = adsp_rpc_init(module); + if (rc) + goto done; + + module->ops = ops; + module->driver_data = driver_data; + *out = module; + rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_REGISTER_APP, + module->id, module); + if (rc) { + module->ops = NULL; + module->driver_data = NULL; + *out = NULL; + pr_err("adsp: REGISTER_APP failed\n"); + goto done; + } + + pr_info("adsp: module %s has been registered\n", module->name); + +done: + mutex_lock(&adsp_open_lock); + if (rc && --adsp_open_count == 0) { + disable_irq(INT_ADSP); + allow_suspend(); + } + if (rc && --module->open_count == 0 && module->clk) + clk_disable(module->clk); + mutex_unlock(&adsp_open_lock); + mutex_unlock(&module->lock); + return rc; +} +EXPORT_SYMBOL(msm_adsp_get); + +static int msm_adsp_disable_locked(struct msm_adsp_module *module); + +void msm_adsp_put(struct msm_adsp_module *module) +{ + unsigned long flags; + + mutex_lock(&module->lock); + if (--module->open_count == 0 && module->clk) + clk_disable(module->clk); + if (module->ops) { + pr_info("adsp: closing module %s\n", module->name); + + /* lock to ensure a dsp event cannot be delivered + * during or after removal of the ops and driver_data + */ + spin_lock_irqsave(&adsp_cmd_lock, flags); + module->ops = NULL; + module->driver_data = NULL; + spin_unlock_irqrestore(&adsp_cmd_lock, flags); + + if (module->state != ADSP_STATE_DISABLED) { + pr_info("adsp: disabling module %s\n", module->name); + msm_adsp_disable_locked(module); + } + + msm_rpc_close(module->rpc_client); + module->rpc_client = 0; + if (--adsp_open_count == 0) { + disable_irq(INT_ADSP); + allow_suspend(); + pr_info("adsp: disable interrupt\n"); + } + } else { + pr_info("adsp: module %s is already closed\n", module->name); + } + mutex_unlock(&module->lock); +} +EXPORT_SYMBOL(msm_adsp_put); + +/* this should be common code with rpc_servers.c */ +static int rpc_send_accepted_void_reply(struct msm_rpc_endpoint *client, + uint32_t xid, uint32_t accept_status) +{ + int rc = 0; + uint8_t reply_buf[sizeof(struct rpc_reply_hdr)]; + struct rpc_reply_hdr *reply = (struct rpc_reply_hdr *)reply_buf; + + reply->xid = cpu_to_be32(xid); + reply->type = cpu_to_be32(1); /* reply */ + reply->reply_stat = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED); + + reply->data.acc_hdr.accept_stat = cpu_to_be32(accept_status); + reply->data.acc_hdr.verf_flavor = 0; + reply->data.acc_hdr.verf_length = 0; + + rc = msm_rpc_write(rpc_cb_server_client, reply_buf, sizeof(reply_buf)); + if (rc < 0) + pr_err("adsp: could not write RPC response: %d\n", rc); + return rc; +} + +int __msm_adsp_write(struct msm_adsp_module *module, unsigned dsp_queue_addr, + void *cmd_buf, size_t cmd_size) +{ + uint32_t ctrl_word; + uint32_t dsp_q_addr; + uint32_t dsp_addr; + uint32_t cmd_id = 0; + int cnt = 0; + int ret_status = 0; + unsigned long flags; + struct adsp_info *info = module->info; + + spin_lock_irqsave(&adsp_cmd_lock, flags); + + if (module->state != ADSP_STATE_ENABLED) { + spin_unlock_irqrestore(&adsp_cmd_lock, flags); + pr_err("adsp: module %s not enabled before write\n", + module->name); + return -ENODEV; + } + if (adsp_validate_module(module->id)) { + spin_unlock_irqrestore(&adsp_cmd_lock, flags); + pr_info("adsp: module id validation failed %s %d\n", + module->name, module->id); + return -ENXIO; + } + dsp_q_addr = adsp_get_queue_offset(info, dsp_queue_addr); + dsp_q_addr &= ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M; + + /* Poll until the ADSP is ready to accept a command. + * Wait for 100us, return error if it's not responding. + * If this returns an error, we need to disable ALL modules and + * then retry. + */ + while (((ctrl_word = readl(info->write_ctrl)) & + ADSP_RTOS_WRITE_CTRL_WORD_READY_M) != + ADSP_RTOS_WRITE_CTRL_WORD_READY_V) { + if (cnt > 100) { + pr_err("adsp: timeout waiting for DSP write ready\n"); + ret_status = -EIO; + goto fail; + } + pr_warning("adsp: waiting for DSP write ready\n"); + udelay(1); + cnt++; + } + + /* Set the mutex bits */ + ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M); + ctrl_word |= ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V; + + /* Clear the command bits */ + ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_CMD_M); + + /* Set the queue address bits */ + ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M); + ctrl_word |= dsp_q_addr; + + writel(ctrl_word, info->write_ctrl); + + /* Generate an interrupt to the DSP. This notifies the DSP that + * we are about to send a command on this particular queue. The + * DSP will in response change its state. + */ + writel(1, info->send_irq); + + /* Poll until the adsp responds to the interrupt; this does not + * generate an interrupt from the adsp. This should happen within + * 5ms. + */ + cnt = 0; + while ((readl(info->write_ctrl) & + ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M) == + ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V) { + if (cnt > 5000) { + pr_err("adsp: timeout waiting for adsp ack\n"); + ret_status = -EIO; + goto fail; + } + udelay(1); + cnt++; + } + + /* Read the ctrl word */ + ctrl_word = readl(info->write_ctrl); + + if ((ctrl_word & ADSP_RTOS_WRITE_CTRL_WORD_STATUS_M) != + ADSP_RTOS_WRITE_CTRL_WORD_NO_ERR_V) { + ret_status = -EAGAIN; + goto fail; + } + + /* Ctrl word status bits were 00, no error in the ctrl word */ + + /* Get the DSP buffer address */ + dsp_addr = (ctrl_word & ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M) + + (uint32_t)MSM_AD5_BASE; + + if (dsp_addr < (uint32_t)(MSM_AD5_BASE + QDSP_RAMC_OFFSET)) { + uint16_t *buf_ptr = (uint16_t *) cmd_buf; + uint16_t *dsp_addr16 = (uint16_t *)dsp_addr; + cmd_size /= sizeof(uint16_t); + + /* Save the command ID */ + cmd_id = (uint32_t) buf_ptr[0]; + + /* Copy the command to DSP memory */ + cmd_size++; + while (--cmd_size) + *dsp_addr16++ = *buf_ptr++; + } else { + uint32_t *buf_ptr = (uint32_t *) cmd_buf; + uint32_t *dsp_addr32 = (uint32_t *)dsp_addr; + cmd_size /= sizeof(uint32_t); + + /* Save the command ID */ + cmd_id = buf_ptr[0]; + + cmd_size++; + while (--cmd_size) + *dsp_addr32++ = *buf_ptr++; + } + + /* Set the mutex bits */ + ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M); + ctrl_word |= ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V; + + /* Set the command bits to write done */ + ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_CMD_M); + ctrl_word |= ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_DONE_V; + + /* Set the queue address bits */ + ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M); + ctrl_word |= dsp_q_addr; + + writel(ctrl_word, info->write_ctrl); + + /* Generate an interrupt to the DSP. It does not respond with + * an interrupt, and we do not need to wait for it to + * acknowledge, because it will hold the mutex lock until it's + * ready to receive more commands again. + */ + writel(1, info->send_irq); + + module->num_commands++; + +fail: + spin_unlock_irqrestore(&adsp_cmd_lock, flags); + return ret_status; +} +EXPORT_SYMBOL(msm_adsp_write); + +int msm_adsp_write(struct msm_adsp_module *module, unsigned dsp_queue_addr, + void *cmd_buf, size_t cmd_size) +{ + int rc, retries = 0; + do { + rc = __msm_adsp_write(module, dsp_queue_addr, cmd_buf, cmd_size); + if (rc == -EAGAIN) + udelay(10); + } while(rc == -EAGAIN && retries++ < 100); + if (retries > 50) + pr_warning("adsp: %s command took %d attempts: rc %d\n", + module->name, retries, rc); + return rc; +} + +#ifdef CONFIG_MSM_ADSP_REPORT_EVENTS +static void *modem_event_addr; +#if CONFIG_MSM_AMSS_VERSION >= 6350 +static void read_modem_event(void *buf, size_t len) +{ + uint32_t *dptr = buf; + struct rpc_adsp_rtos_modem_to_app_args_t *sptr; + struct adsp_rtos_mp_mtoa_type *pkt_ptr; + + sptr = modem_event_addr; + pkt_ptr = &sptr->mtoa_pkt.adsp_rtos_mp_mtoa_data.mp_mtoa_packet; + + dptr[0] = be32_to_cpu(sptr->mtoa_pkt.mp_mtoa_header.event); + dptr[1] = be32_to_cpu(pkt_ptr->module); + dptr[2] = be32_to_cpu(pkt_ptr->image); +} +#else +static void read_modem_event(void *buf, size_t len) +{ + uint32_t *dptr = buf; + struct rpc_adsp_rtos_modem_to_app_args_t *sptr = + modem_event_addr; + dptr[0] = be32_to_cpu(sptr->event); + dptr[1] = be32_to_cpu(sptr->module); + dptr[2] = be32_to_cpu(sptr->image); +} +#endif /* CONFIG_MSM_AMSS_VERSION >= 6350 */ +#endif /* CONFIG_MSM_ADSP_REPORT_EVENTS */ + +static void handle_adsp_rtos_mtoa_app(struct rpc_request_hdr *req) +{ + struct rpc_adsp_rtos_modem_to_app_args_t *args = + (struct rpc_adsp_rtos_modem_to_app_args_t *)req; + uint32_t event; + uint32_t proc_id; + uint32_t module_id; + uint32_t image; + struct msm_adsp_module *module; +#if CONFIG_MSM_AMSS_VERSION >= 6350 + struct adsp_rtos_mp_mtoa_type *pkt_ptr = + &args->mtoa_pkt.adsp_rtos_mp_mtoa_data.mp_mtoa_packet; + + event = be32_to_cpu(args->mtoa_pkt.mp_mtoa_header.event); + proc_id = be32_to_cpu(args->mtoa_pkt.mp_mtoa_header.proc_id); + module_id = be32_to_cpu(pkt_ptr->module); + image = be32_to_cpu(pkt_ptr->image); + + if (be32_to_cpu(args->mtoa_pkt.desc_field) == RPC_ADSP_RTOS_INIT_INFO) { + struct queue_to_offset_type *qptr; + struct queue_to_offset_type *qtbl; + uint32_t *mptr; + uint32_t *mtbl; + uint32_t q_idx; + uint32_t num_entries; + uint32_t entries_per_image; + struct adsp_rtos_mp_mtoa_init_info_type *iptr; + struct adsp_rtos_mp_mtoa_init_info_type *sptr; + int32_t i_no, e_idx; + + pr_info("adsp:INIT_INFO Event\n"); + sptr = &args->mtoa_pkt.adsp_rtos_mp_mtoa_data. + mp_mtoa_init_packet; + + iptr = adsp_info.init_info_ptr; + iptr->image_count = be32_to_cpu(sptr->image_count); + iptr->num_queue_offsets = be32_to_cpu(sptr->num_queue_offsets); + num_entries = iptr->num_queue_offsets; + qptr = &sptr->queue_offsets_tbl[0][0]; + for (i_no = 0; i_no < iptr->image_count; i_no++) { + qtbl = &iptr->queue_offsets_tbl[i_no][0]; + for (e_idx = 0; e_idx < num_entries; e_idx++) { + qtbl[e_idx].offset = be32_to_cpu(qptr->offset); + qtbl[e_idx].queue = be32_to_cpu(qptr->queue); + q_idx = be32_to_cpu(qptr->queue); + iptr->queue_offsets[i_no][q_idx] = + qtbl[e_idx].offset; + qptr++; + } + } + + num_entries = be32_to_cpu(sptr->num_task_module_entries); + iptr->num_task_module_entries = num_entries; + entries_per_image = num_entries / iptr->image_count; + mptr = &sptr->task_to_module_tbl[0][0]; + for (i_no = 0; i_no < iptr->image_count; i_no++) { + mtbl = &iptr->task_to_module_tbl[i_no][0]; + for (e_idx = 0; e_idx < entries_per_image; e_idx++) { + mtbl[e_idx] = be32_to_cpu(*mptr); + mptr++; + } + } + + iptr->module_table_size = be32_to_cpu(sptr->module_table_size); + mptr = &sptr->module_entries[0]; + for (i_no = 0; i_no < iptr->module_table_size; i_no++) + iptr->module_entries[i_no] = be32_to_cpu(mptr[i_no]); + adsp_info.init_info_state = ADSP_STATE_INIT_INFO; + rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid, + RPC_ACCEPTSTAT_SUCCESS); + wake_up(&adsp_info.init_info_wait); + + return; + } +#else + event = be32_to_cpu(args->event); + proc_id = be32_to_cpu(args->proc_id); + module_id = be32_to_cpu(args->module); + image = be32_to_cpu(args->image); +#endif + + pr_info("adsp: rpc event=%d, proc_id=%d, module=%d, image=%d\n", + event, proc_id, module_id, image); + + module = find_adsp_module_by_id(&adsp_info, module_id); + if (!module) { + pr_err("adsp: module %d is not supported!\n", module_id); + rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid, + RPC_ACCEPTSTAT_GARBAGE_ARGS); + return; + } + + mutex_lock(&module->lock); + switch (event) { + case RPC_ADSP_RTOS_MOD_READY: + pr_info("adsp: module %s: READY\n", module->name); + module->state = ADSP_STATE_ENABLED; + wake_up(&module->state_wait); + adsp_set_image(module->info, image); + break; + case RPC_ADSP_RTOS_MOD_DISABLE: + pr_info("adsp: module %s: DISABLED\n", module->name); + module->state = ADSP_STATE_DISABLED; + wake_up(&module->state_wait); + break; + case RPC_ADSP_RTOS_SERVICE_RESET: + pr_info("adsp: module %s: SERVICE_RESET\n", module->name); + module->state = ADSP_STATE_DISABLED; + wake_up(&module->state_wait); + break; + case RPC_ADSP_RTOS_CMD_SUCCESS: + pr_info("adsp: module %s: CMD_SUCCESS\n", module->name); + break; + case RPC_ADSP_RTOS_CMD_FAIL: + pr_info("adsp: module %s: CMD_FAIL\n", module->name); + break; +#if CONFIG_MSM_AMSS_VERSION >= 6350 + case RPC_ADSP_RTOS_DISABLE_FAIL: + pr_info("adsp: module %s: DISABLE_FAIL\n", module->name); + break; +#endif + default: + pr_info("adsp: unknown event %d\n", event); + rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid, + RPC_ACCEPTSTAT_GARBAGE_ARGS); + mutex_unlock(&module->lock); + return; + } + rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid, + RPC_ACCEPTSTAT_SUCCESS); + mutex_unlock(&module->lock); +#ifdef CONFIG_MSM_ADSP_REPORT_EVENTS + modem_event_addr = (uint32_t *)req; + module->ops->event(module->driver_data, EVENT_MSG_ID, + EVENT_LEN, read_modem_event); +#endif +} + +static int handle_adsp_rtos_mtoa(struct rpc_request_hdr *req) +{ + switch (req->procedure) { + case RPC_ADSP_RTOS_MTOA_NULL_PROC: + rpc_send_accepted_void_reply(rpc_cb_server_client, + req->xid, + RPC_ACCEPTSTAT_SUCCESS); + break; + case RPC_ADSP_RTOS_MODEM_TO_APP_PROC: + handle_adsp_rtos_mtoa_app(req); + break; + default: + pr_err("adsp: unknowned proc %d\n", req->procedure); + rpc_send_accepted_void_reply( + rpc_cb_server_client, req->xid, + RPC_ACCEPTSTAT_PROC_UNAVAIL); + break; + } + return 0; +} + +/* this should be common code with rpc_servers.c */ +static int adsp_rpc_thread(void *data) +{ + void *buffer; + struct rpc_request_hdr *req; + int rc; + + do { + rc = msm_rpc_read(rpc_cb_server_client, &buffer, -1, -1); + if (rc < 0) { + pr_err("adsp: could not read rpc: %d\n", rc); + break; + } + req = (struct rpc_request_hdr *)buffer; + + req->type = be32_to_cpu(req->type); + req->xid = be32_to_cpu(req->xid); + req->rpc_vers = be32_to_cpu(req->rpc_vers); + req->prog = be32_to_cpu(req->prog); + req->vers = be32_to_cpu(req->vers); + req->procedure = be32_to_cpu(req->procedure); + + if (req->type != 0) + goto bad_rpc; + if (req->rpc_vers != 2) + goto bad_rpc; + if (req->prog != RPC_ADSP_RTOS_MTOA_PROG) + goto bad_rpc; + if (req->vers != RPC_ADSP_RTOS_MTOA_VERS) + goto bad_rpc; + + handle_adsp_rtos_mtoa(req); + kfree(buffer); + continue; + +bad_rpc: + pr_err("adsp: bogus rpc from modem\n"); + kfree(buffer); + } while (1); + + do_exit(0); +} + +static size_t read_event_size; +static void *read_event_addr; + +static void read_event_16(void *buf, size_t len) +{ + uint16_t *dst = buf; + uint16_t *src = read_event_addr; + len /= 2; + if (len > read_event_size) + len = read_event_size; + while (len--) + *dst++ = *src++; +} + +static void read_event_32(void *buf, size_t len) +{ + uint32_t *dst = buf; + uint32_t *src = read_event_addr; + len /= 2; + if (len > read_event_size) + len = read_event_size; + while (len--) + *dst++ = *src++; +} + +static int adsp_rtos_read_ctrl_word_cmd_tast_to_h_v( + struct adsp_info *info, void *dsp_addr) +{ + struct msm_adsp_module *module; + unsigned rtos_task_id; + unsigned msg_id; + unsigned msg_length; + void (*func)(void *, size_t); + + if (dsp_addr >= (void *)(MSM_AD5_BASE + QDSP_RAMC_OFFSET)) { + uint32_t *dsp_addr32 = dsp_addr; + uint32_t tmp = *dsp_addr32++; + rtos_task_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M) >> 8; + msg_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M); + read_event_size = tmp >> 16; + read_event_addr = dsp_addr32; + msg_length = read_event_size * sizeof(uint32_t); + func = read_event_32; + } else { + uint16_t *dsp_addr16 = dsp_addr; + uint16_t tmp = *dsp_addr16++; + rtos_task_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M) >> 8; + msg_id = tmp & ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M; + read_event_size = *dsp_addr16++; + read_event_addr = dsp_addr16; + msg_length = read_event_size * sizeof(uint16_t); + func = read_event_16; + } + + if (rtos_task_id > info->max_task_id) { + pr_err("adsp: bogus task id %d\n", rtos_task_id); + return 0; + } + module = find_adsp_module_by_id(info, + adsp_get_module(info, rtos_task_id)); + + if (!module) { + pr_err("adsp: no module for task id %d\n", rtos_task_id); + return 0; + } + + module->num_events++; + + if (!module->ops) { + pr_err("adsp: module %s is not open\n", module->name); + return 0; + } + + module->ops->event(module->driver_data, msg_id, msg_length, func); + return 0; +} + +static int adsp_get_event(struct adsp_info *info) +{ + uint32_t ctrl_word; + uint32_t ready; + void *dsp_addr; + uint32_t cmd_type; + int cnt; + unsigned long flags; + int rc = 0; + + spin_lock_irqsave(&adsp_cmd_lock, flags); + + /* Whenever the DSP has a message, it updates this control word + * and generates an interrupt. When we receive the interrupt, we + * read this register to find out what ADSP task the command is + * comming from. + * + * The ADSP should *always* be ready on the first call, but the + * irq handler calls us in a loop (to handle back-to-back command + * processing), so we give the DSP some time to return to the + * ready state. The DSP will not issue another IRQ for events + * pending between the first IRQ and the event queue being drained, + * unfortunately. + */ + + for (cnt = 0; cnt < 10; cnt++) { + ctrl_word = readl(info->read_ctrl); + + if ((ctrl_word & ADSP_RTOS_READ_CTRL_WORD_FLAG_M) == + ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_CONT_V) + goto ready; + + udelay(10); + } + pr_warning("adsp: not ready after 100uS\n"); + rc = -EBUSY; + goto done; + +ready: + /* Here we check to see if there are pending messages. If there are + * none, we siply return -EAGAIN to indicate that there are no more + * messages pending. + */ + ready = ctrl_word & ADSP_RTOS_READ_CTRL_WORD_READY_M; + if ((ready != ADSP_RTOS_READ_CTRL_WORD_READY_V) && + (ready != ADSP_RTOS_READ_CTRL_WORD_CONT_V)) { + rc = -EAGAIN; + goto done; + } + + /* DSP says that there are messages waiting for the host to read */ + + /* Get the Command Type */ + cmd_type = ctrl_word & ADSP_RTOS_READ_CTRL_WORD_CMD_TYPE_M; + + /* Get the DSP buffer address */ + dsp_addr = (void *)((ctrl_word & + ADSP_RTOS_READ_CTRL_WORD_DSP_ADDR_M) + + (uint32_t)MSM_AD5_BASE); + + /* We can only handle Task-to-Host messages */ + if (cmd_type != ADSP_RTOS_READ_CTRL_WORD_CMD_TASK_TO_H_V) { + pr_err("adsp: unknown dsp cmd_type %d\n", cmd_type); + rc = -EIO; + goto done; + } + + adsp_rtos_read_ctrl_word_cmd_tast_to_h_v(info, dsp_addr); + + ctrl_word = readl(info->read_ctrl); + ctrl_word &= ~ADSP_RTOS_READ_CTRL_WORD_READY_M; + + /* Write ctrl word to the DSP */ + writel(ctrl_word, info->read_ctrl); + + /* Generate an interrupt to the DSP */ + writel(1, info->send_irq); + +done: + spin_unlock_irqrestore(&adsp_cmd_lock, flags); + return rc; +} + +static irqreturn_t adsp_irq_handler(int irq, void *data) +{ + struct adsp_info *info = &adsp_info; + int cnt = 0; + for (cnt = 0; cnt < 10; cnt++) + if (adsp_get_event(info) < 0) + break; + if (cnt > info->event_backlog_max) + info->event_backlog_max = cnt; + info->events_received += cnt; + if (cnt == 10) + pr_err("adsp: too many (%d) events for single irq!\n", cnt); + return IRQ_HANDLED; +} + +int adsp_set_clkrate(struct msm_adsp_module *module, unsigned long clk_rate) +{ + if (module->clk && clk_rate) + return clk_set_rate(module->clk, clk_rate); + + return -EINVAL; +} + +int msm_adsp_enable(struct msm_adsp_module *module) +{ + int rc = 0; + + pr_info("msm_adsp_enable() '%s'state[%d] id[%d]\n", + module->name, module->state, module->id); + + mutex_lock(&module->lock); + switch (module->state) { + case ADSP_STATE_DISABLED: + rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_ENABLE, + module->id, module); + if (rc) + break; + module->state = ADSP_STATE_ENABLING; + mutex_unlock(&module->lock); + rc = wait_event_timeout(module->state_wait, + module->state != ADSP_STATE_ENABLING, + 1 * HZ); + mutex_lock(&module->lock); + if (module->state == ADSP_STATE_ENABLED) { + rc = 0; + } else { + pr_err("adsp: module '%s' enable timed out\n", + module->name); + rc = -ETIMEDOUT; + } + break; + case ADSP_STATE_ENABLING: + pr_warning("adsp: module '%s' enable in progress\n", + module->name); + break; + case ADSP_STATE_ENABLED: + pr_warning("adsp: module '%s' already enabled\n", + module->name); + break; + case ADSP_STATE_DISABLING: + pr_err("adsp: module '%s' disable in progress\n", + module->name); + rc = -EBUSY; + break; + } + mutex_unlock(&module->lock); + return rc; +} +EXPORT_SYMBOL(msm_adsp_enable); + +static int msm_adsp_disable_locked(struct msm_adsp_module *module) +{ + int rc = 0; + + switch (module->state) { + case ADSP_STATE_DISABLED: + pr_warning("adsp: module '%s' already disabled\n", + module->name); + break; + case ADSP_STATE_ENABLING: + case ADSP_STATE_ENABLED: + rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_DISABLE, + module->id, module); + module->state = ADSP_STATE_DISABLED; + } + return rc; +} + +int msm_adsp_disable(struct msm_adsp_module *module) +{ + int rc; + pr_info("msm_adsp_disable() '%s'\n", module->name); + mutex_lock(&module->lock); + rc = msm_adsp_disable_locked(module); + mutex_unlock(&module->lock); + return rc; +} +EXPORT_SYMBOL(msm_adsp_disable); + +static int msm_adsp_probe(struct platform_device *pdev) +{ + unsigned count; + int rc, i; + int max_module_id; + + pr_info("adsp: probe\n"); + +#if CONFIG_MSM_AMSS_VERSION >= 6350 + adsp_info.init_info_ptr = kzalloc( + (sizeof(struct adsp_rtos_mp_mtoa_init_info_type)), GFP_KERNEL); + if (!adsp_info.init_info_ptr) + return -ENOMEM; +#endif + + rc = adsp_init_info(&adsp_info); + if (rc) + return rc; + adsp_info.send_irq += (uint32_t) MSM_AD5_BASE; + adsp_info.read_ctrl += (uint32_t) MSM_AD5_BASE; + adsp_info.write_ctrl += (uint32_t) MSM_AD5_BASE; + count = adsp_info.module_count; + +#if CONFIG_MSM_AMSS_VERSION >= 6350 + max_module_id = count; +#else + max_module_id = adsp_info.max_module_id + 1; +#endif + + adsp_modules = kzalloc( + sizeof(struct msm_adsp_module) * count + + sizeof(void *) * max_module_id, GFP_KERNEL); + if (!adsp_modules) + return -ENOMEM; + + adsp_info.id_to_module = (void *) (adsp_modules + count); + + spin_lock_init(&adsp_cmd_lock); + + rc = request_irq(INT_ADSP, adsp_irq_handler, IRQF_TRIGGER_RISING, + "adsp", 0); + if (rc < 0) + goto fail_request_irq; + disable_irq(INT_ADSP); + + rpc_cb_server_client = msm_rpc_open(); + if (IS_ERR(rpc_cb_server_client)) { + rpc_cb_server_client = NULL; + rc = PTR_ERR(rpc_cb_server_client); + pr_err("adsp: could not create rpc server (%d)\n", rc); + goto fail_rpc_open; + } + + rc = msm_rpc_register_server(rpc_cb_server_client, + RPC_ADSP_RTOS_MTOA_PROG, + RPC_ADSP_RTOS_MTOA_VERS); + if (rc) { + pr_err("adsp: could not register callback server (%d)\n", rc); + goto fail_rpc_register; + } + + /* start the kernel thread to process the callbacks */ + kthread_run(adsp_rpc_thread, NULL, "kadspd"); + + for (i = 0; i < count; i++) { + struct msm_adsp_module *mod = adsp_modules + i; + mutex_init(&mod->lock); + init_waitqueue_head(&mod->state_wait); + mod->info = &adsp_info; + mod->name = adsp_info.module[i].name; + mod->id = adsp_info.module[i].id; + if (adsp_info.module[i].clk_name) + mod->clk = clk_get(NULL, adsp_info.module[i].clk_name); + else + mod->clk = NULL; + if (mod->clk && adsp_info.module[i].clk_rate) + clk_set_rate(mod->clk, adsp_info.module[i].clk_rate); + mod->verify_cmd = adsp_info.module[i].verify_cmd; + mod->patch_event = adsp_info.module[i].patch_event; + INIT_HLIST_HEAD(&mod->pmem_regions); + mod->pdev.name = adsp_info.module[i].pdev_name; + mod->pdev.id = -1; +#if CONFIG_MSM_AMSS_VERSION >= 6350 + adsp_info.id_to_module[i] = mod; +#else + adsp_info.id_to_module[mod->id] = mod; +#endif + platform_device_register(&mod->pdev); + } + + msm_adsp_publish_cdevs(adsp_modules, count); + + return 0; + +fail_rpc_register: + msm_rpc_close(rpc_cb_server_client); + rpc_cb_server_client = NULL; +fail_rpc_open: + enable_irq(INT_ADSP); + free_irq(INT_ADSP, 0); +fail_request_irq: + kfree(adsp_modules); +#if CONFIG_MSM_AMSS_VERSION >= 6350 + kfree(adsp_info.init_info_ptr); +#endif + return rc; +} + +static struct platform_driver msm_adsp_driver = { + .probe = msm_adsp_probe, + .driver = { + .name = MSM_ADSP_DRIVER_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init adsp_init(void) +{ + return platform_driver_register(&msm_adsp_driver); +} + +device_initcall(adsp_init); diff --git a/trunk/drivers/staging/dream/qdsp5/adsp.h b/trunk/drivers/staging/dream/qdsp5/adsp.h new file mode 100644 index 000000000000..0e5c9abd3da5 --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/adsp.h @@ -0,0 +1,369 @@ +/* arch/arm/mach-msm/qdsp5/adsp.h + * + * Copyright (c) 2008 QUALCOMM Incorporated + * Copyright (C) 2008 Google, Inc. + * Author: Iliyan Malchev + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _ARCH_ARM_MACH_MSM_ADSP_H +#define _ARCH_ARM_MACH_MSM_ADSP_H + +#include +#include +#include +#include + +int adsp_pmem_fixup(struct msm_adsp_module *module, void **addr, + unsigned long len); +int adsp_pmem_fixup_kvaddr(struct msm_adsp_module *module, void **addr, + unsigned long *kvaddr, unsigned long len); +int adsp_pmem_paddr_fixup(struct msm_adsp_module *module, void **addr); + +int adsp_vfe_verify_cmd(struct msm_adsp_module *module, + unsigned int queue_id, void *cmd_data, + size_t cmd_size); +int adsp_jpeg_verify_cmd(struct msm_adsp_module *module, + unsigned int queue_id, void *cmd_data, + size_t cmd_size); +int adsp_lpm_verify_cmd(struct msm_adsp_module *module, + unsigned int queue_id, void *cmd_data, + size_t cmd_size); +int adsp_video_verify_cmd(struct msm_adsp_module *module, + unsigned int queue_id, void *cmd_data, + size_t cmd_size); +int adsp_videoenc_verify_cmd(struct msm_adsp_module *module, + unsigned int queue_id, void *cmd_data, + size_t cmd_size); + + +struct adsp_event; + +int adsp_vfe_patch_event(struct msm_adsp_module *module, + struct adsp_event *event); + +int adsp_jpeg_patch_event(struct msm_adsp_module *module, + struct adsp_event *event); + + +struct adsp_module_info { + const char *name; + const char *pdev_name; + uint32_t id; + const char *clk_name; + unsigned long clk_rate; + int (*verify_cmd) (struct msm_adsp_module*, unsigned int, void *, + size_t); + int (*patch_event) (struct msm_adsp_module*, struct adsp_event *); +}; + +#define ADSP_EVENT_MAX_SIZE 496 +#define EVENT_LEN 12 +#define EVENT_MSG_ID ((uint16_t)~0) + +struct adsp_event { + struct list_head list; + uint32_t size; /* always in bytes */ + uint16_t msg_id; + uint16_t type; /* 0 for msgs (from aDSP), -1 for events (from ARM9) */ + int is16; /* always 0 (msg is 32-bit) when the event type is 1(ARM9) */ + union { + uint16_t msg16[ADSP_EVENT_MAX_SIZE / 2]; + uint32_t msg32[ADSP_EVENT_MAX_SIZE / 4]; + } data; +}; + +struct adsp_info { + uint32_t send_irq; + uint32_t read_ctrl; + uint32_t write_ctrl; + + uint32_t max_msg16_size; + uint32_t max_msg32_size; + + uint32_t max_task_id; + uint32_t max_module_id; + uint32_t max_queue_id; + uint32_t max_image_id; + + /* for each image id, a map of queue id to offset */ + uint32_t **queue_offset; + + /* for each image id, a map of task id to module id */ + uint32_t **task_to_module; + + /* for each module id, map of module id to module */ + struct msm_adsp_module **id_to_module; + + uint32_t module_count; + struct adsp_module_info *module; + + /* stats */ + uint32_t events_received; + uint32_t event_backlog_max; + +#if CONFIG_MSM_AMSS_VERSION >= 6350 + /* rpc_client for init_info */ + struct msm_rpc_endpoint *init_info_rpc_client; + struct adsp_rtos_mp_mtoa_init_info_type *init_info_ptr; + wait_queue_head_t init_info_wait; + unsigned init_info_state; +#endif +}; + +#define RPC_ADSP_RTOS_ATOM_PROG 0x3000000a +#define RPC_ADSP_RTOS_MTOA_PROG 0x3000000b +#define RPC_ADSP_RTOS_ATOM_NULL_PROC 0 +#define RPC_ADSP_RTOS_MTOA_NULL_PROC 0 +#define RPC_ADSP_RTOS_APP_TO_MODEM_PROC 2 +#define RPC_ADSP_RTOS_MODEM_TO_APP_PROC 2 + +#if CONFIG_MSM_AMSS_VERSION >= 6350 +#define RPC_ADSP_RTOS_ATOM_VERS MSM_RPC_VERS(1,0) +#define RPC_ADSP_RTOS_MTOA_VERS MSM_RPC_VERS(2,1) /* must be actual vers */ +#define MSM_ADSP_DRIVER_NAME "rs3000000a:00010000" +#elif (CONFIG_MSM_AMSS_VERSION == 6220) || (CONFIG_MSM_AMSS_VERSION == 6225) +#define RPC_ADSP_RTOS_ATOM_VERS MSM_RPC_VERS(0x71d1094b, 0) +#define RPC_ADSP_RTOS_MTOA_VERS MSM_RPC_VERS(0xee3a9966, 0) +#define MSM_ADSP_DRIVER_NAME "rs3000000a:71d1094b" +#elif CONFIG_MSM_AMSS_VERSION == 6210 +#define RPC_ADSP_RTOS_ATOM_VERS MSM_RPC_VERS(0x20f17fd3, 0) +#define RPC_ADSP_RTOS_MTOA_VERS MSM_RPC_VERS(0x75babbd6, 0) +#define MSM_ADSP_DRIVER_NAME "rs3000000a:20f17fd3" +#else +#error "Unknown AMSS version" +#endif + +enum rpc_adsp_rtos_proc_type { + RPC_ADSP_RTOS_PROC_NONE = 0, + RPC_ADSP_RTOS_PROC_MODEM = 1, + RPC_ADSP_RTOS_PROC_APPS = 2, +}; + +enum { + RPC_ADSP_RTOS_CMD_REGISTER_APP, + RPC_ADSP_RTOS_CMD_ENABLE, + RPC_ADSP_RTOS_CMD_DISABLE, + RPC_ADSP_RTOS_CMD_KERNEL_COMMAND, + RPC_ADSP_RTOS_CMD_16_COMMAND, + RPC_ADSP_RTOS_CMD_32_COMMAND, + RPC_ADSP_RTOS_CMD_DISABLE_EVENT_RSP, + RPC_ADSP_RTOS_CMD_REMOTE_EVENT, + RPC_ADSP_RTOS_CMD_SET_STATE, +#if CONFIG_MSM_AMSS_VERSION >= 6350 + RPC_ADSP_RTOS_CMD_REMOTE_INIT_INFO_EVENT, + RPC_ADSP_RTOS_CMD_GET_INIT_INFO, +#endif +}; + +enum rpc_adsp_rtos_mod_status_type { + RPC_ADSP_RTOS_MOD_READY, + RPC_ADSP_RTOS_MOD_DISABLE, + RPC_ADSP_RTOS_SERVICE_RESET, + RPC_ADSP_RTOS_CMD_FAIL, + RPC_ADSP_RTOS_CMD_SUCCESS, +#if CONFIG_MSM_AMSS_VERSION >= 6350 + RPC_ADSP_RTOS_INIT_INFO, + RPC_ADSP_RTOS_DISABLE_FAIL, +#endif +}; + +struct rpc_adsp_rtos_app_to_modem_args_t { + struct rpc_request_hdr hdr; + uint32_t gotit; /* if 1, the next elements are present */ + uint32_t cmd; /* e.g., RPC_ADSP_RTOS_CMD_REGISTER_APP */ + uint32_t proc_id; /* e.g., RPC_ADSP_RTOS_PROC_APPS */ + uint32_t module; /* e.g., QDSP_MODULE_AUDPPTASK */ +}; + +#if CONFIG_MSM_AMSS_VERSION >= 6350 +enum qdsp_image_type { + QDSP_IMAGE_COMBO, + QDSP_IMAGE_GAUDIO, + QDSP_IMAGE_QTV_LP, + QDSP_IMAGE_MAX, + /* DO NOT USE: Force this enum to be a 32bit type to improve speed */ + QDSP_IMAGE_32BIT_DUMMY = 0x10000 +}; + +struct adsp_rtos_mp_mtoa_header_type { + enum rpc_adsp_rtos_mod_status_type event; + enum rpc_adsp_rtos_proc_type proc_id; +}; + +/* ADSP RTOS MP Communications - Modem to APP's Event Info*/ +struct adsp_rtos_mp_mtoa_type { + uint32_t module; + uint32_t image; + uint32_t apps_okts; +}; + +/* ADSP RTOS MP Communications - Modem to APP's Init Info */ +#define IMG_MAX 8 +#define ENTRIES_MAX 64 + +struct queue_to_offset_type { + uint32_t queue; + uint32_t offset; +}; + +struct adsp_rtos_mp_mtoa_init_info_type { + uint32_t image_count; + uint32_t num_queue_offsets; + struct queue_to_offset_type queue_offsets_tbl[IMG_MAX][ENTRIES_MAX]; + uint32_t num_task_module_entries; + uint32_t task_to_module_tbl[IMG_MAX][ENTRIES_MAX]; + + uint32_t module_table_size; + uint32_t module_entries[ENTRIES_MAX]; + /* + * queue_offsets[] is to store only queue_offsets + */ + uint32_t queue_offsets[IMG_MAX][ENTRIES_MAX]; +}; + +struct adsp_rtos_mp_mtoa_s_type { + struct adsp_rtos_mp_mtoa_header_type mp_mtoa_header; + + uint32_t desc_field; + union { + struct adsp_rtos_mp_mtoa_init_info_type mp_mtoa_init_packet; + struct adsp_rtos_mp_mtoa_type mp_mtoa_packet; + } adsp_rtos_mp_mtoa_data; +}; + +struct rpc_adsp_rtos_modem_to_app_args_t { + struct rpc_request_hdr hdr; + uint32_t gotit; /* if 1, the next elements are present */ + struct adsp_rtos_mp_mtoa_s_type mtoa_pkt; +}; +#else +struct rpc_adsp_rtos_modem_to_app_args_t { + struct rpc_request_hdr hdr; + uint32_t gotit; /* if 1, the next elements are present */ + uint32_t event; /* e.g., RPC_ADSP_RTOS_CMD_REGISTER_APP */ + uint32_t proc_id; /* e.g., RPC_ADSP_RTOS_PROC_APPS */ + uint32_t module; /* e.g., QDSP_MODULE_AUDPPTASK */ + uint32_t image; /* RPC_QDSP_IMAGE_GAUDIO */ +}; +#endif /* CONFIG_MSM_AMSS_VERSION >= 6350 */ + +#define ADSP_STATE_DISABLED 0 +#define ADSP_STATE_ENABLING 1 +#define ADSP_STATE_ENABLED 2 +#define ADSP_STATE_DISABLING 3 +#if CONFIG_MSM_AMSS_VERSION >= 6350 +#define ADSP_STATE_INIT_INFO 4 +#endif + +struct msm_adsp_module { + struct mutex lock; + const char *name; + unsigned id; + struct adsp_info *info; + + struct msm_rpc_endpoint *rpc_client; + struct msm_adsp_ops *ops; + void *driver_data; + + /* statistics */ + unsigned num_commands; + unsigned num_events; + + wait_queue_head_t state_wait; + unsigned state; + + struct platform_device pdev; + struct clk *clk; + int open_count; + + struct mutex pmem_regions_lock; + struct hlist_head pmem_regions; + int (*verify_cmd) (struct msm_adsp_module*, unsigned int, void *, + size_t); + int (*patch_event) (struct msm_adsp_module*, struct adsp_event *); +}; + +extern void msm_adsp_publish_cdevs(struct msm_adsp_module *, unsigned); +extern int adsp_init_info(struct adsp_info *info); + +/* Value to indicate that a queue is not defined for a particular image */ +#if CONFIG_MSM_AMSS_VERSION >= 6350 +#define QDSP_RTOS_NO_QUEUE 0xfffffffe +#else +#define QDSP_RTOS_NO_QUEUE 0xffffffff +#endif + +/* + * Constants used to communicate with the ADSP RTOS + */ +#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M 0x80000000U +#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V 0x80000000U +#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_AVAIL_V 0x00000000U + +#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_M 0x70000000U +#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_REQ_V 0x00000000U +#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_DONE_V 0x10000000U +#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_NO_CMD_V 0x70000000U + +#define ADSP_RTOS_WRITE_CTRL_WORD_STATUS_M 0x0E000000U +#define ADSP_RTOS_WRITE_CTRL_WORD_NO_ERR_V 0x00000000U +#define ADSP_RTOS_WRITE_CTRL_WORD_NO_FREE_BUF_V 0x02000000U + +#define ADSP_RTOS_WRITE_CTRL_WORD_KERNEL_FLG_M 0x01000000U +#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_MSG_WRITE_V 0x00000000U +#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_CMD_V 0x01000000U + +#define ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M 0x00FFFFFFU +#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_CMD_ID_M 0x00FFFFFFU + +/* Combination of MUTEX and CMD bits to check if the DSP is busy */ +#define ADSP_RTOS_WRITE_CTRL_WORD_READY_M 0xF0000000U +#define ADSP_RTOS_WRITE_CTRL_WORD_READY_V 0x70000000U + +/* RTOS to Host processor command mask values */ +#define ADSP_RTOS_READ_CTRL_WORD_FLAG_M 0x80000000U +#define ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_WAIT_V 0x00000000U +#define ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_CONT_V 0x80000000U + +#define ADSP_RTOS_READ_CTRL_WORD_CMD_M 0x60000000U +#define ADSP_RTOS_READ_CTRL_WORD_READ_DONE_V 0x00000000U +#define ADSP_RTOS_READ_CTRL_WORD_READ_REQ_V 0x20000000U +#define ADSP_RTOS_READ_CTRL_WORD_NO_CMD_V 0x60000000U + +/* Combination of FLAG and COMMAND bits to check if MSG ready */ +#define ADSP_RTOS_READ_CTRL_WORD_READY_M 0xE0000000U +#define ADSP_RTOS_READ_CTRL_WORD_READY_V 0xA0000000U +#define ADSP_RTOS_READ_CTRL_WORD_CONT_V 0xC0000000U +#define ADSP_RTOS_READ_CTRL_WORD_DONE_V 0xE0000000U + +#define ADSP_RTOS_READ_CTRL_WORD_STATUS_M 0x18000000U +#define ADSP_RTOS_READ_CTRL_WORD_NO_ERR_V 0x00000000U + +#define ADSP_RTOS_READ_CTRL_WORD_IN_PROG_M 0x04000000U +#define ADSP_RTOS_READ_CTRL_WORD_NO_READ_IN_PROG_V 0x00000000U +#define ADSP_RTOS_READ_CTRL_WORD_READ_IN_PROG_V 0x04000000U + +#define ADSP_RTOS_READ_CTRL_WORD_CMD_TYPE_M 0x03000000U +#define ADSP_RTOS_READ_CTRL_WORD_CMD_TASK_TO_H_V 0x00000000U +#define ADSP_RTOS_READ_CTRL_WORD_CMD_KRNL_TO_H_V 0x01000000U +#define ADSP_RTOS_READ_CTRL_WORD_CMD_H_TO_KRNL_CFM_V 0x02000000U + +#define ADSP_RTOS_READ_CTRL_WORD_DSP_ADDR_M 0x00FFFFFFU + +#define ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M 0x000000FFU +#define ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M 0x0000FF00U + +/* Base address of DSP and DSP hardware registers */ +#define QDSP_RAMC_OFFSET 0x400000 + +#endif /* _ARCH_ARM_MACH_MSM_ADSP_H */ diff --git a/trunk/drivers/staging/dream/qdsp5/adsp_6210.c b/trunk/drivers/staging/dream/qdsp5/adsp_6210.c new file mode 100644 index 000000000000..3cf4e99ed862 --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/adsp_6210.c @@ -0,0 +1,283 @@ +/* arch/arm/mach-msm/qdsp5/adsp_6210.h + * + * Copyright (c) 2008 QUALCOMM Incorporated. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "adsp.h" + +/* Firmware modules */ +typedef enum { + QDSP_MODULE_KERNEL, + QDSP_MODULE_AFETASK, + QDSP_MODULE_AUDPLAY0TASK, + QDSP_MODULE_AUDPLAY1TASK, + QDSP_MODULE_AUDPPTASK, + QDSP_MODULE_VIDEOTASK, + QDSP_MODULE_VIDEO_AAC_VOC, + QDSP_MODULE_PCM_DEC, + QDSP_MODULE_AUDIO_DEC_MP3, + QDSP_MODULE_AUDIO_DEC_AAC, + QDSP_MODULE_AUDIO_DEC_WMA, + QDSP_MODULE_HOSTPCM, + QDSP_MODULE_DTMF, + QDSP_MODULE_AUDRECTASK, + QDSP_MODULE_AUDPREPROCTASK, + QDSP_MODULE_SBC_ENC, + QDSP_MODULE_VOC, + QDSP_MODULE_VOC_PCM, + QDSP_MODULE_VOCENCTASK, + QDSP_MODULE_VOCDECTASK, + QDSP_MODULE_VOICEPROCTASK, + QDSP_MODULE_VIDEOENCTASK, + QDSP_MODULE_VFETASK, + QDSP_MODULE_WAV_ENC, + QDSP_MODULE_AACLC_ENC, + QDSP_MODULE_VIDEO_AMR, + QDSP_MODULE_VOC_AMR, + QDSP_MODULE_VOC_EVRC, + QDSP_MODULE_VOC_13K, + QDSP_MODULE_VOC_FGV, + QDSP_MODULE_DIAGTASK, + QDSP_MODULE_JPEGTASK, + QDSP_MODULE_LPMTASK, + QDSP_MODULE_QCAMTASK, + QDSP_MODULE_MODMATHTASK, + QDSP_MODULE_AUDPLAY2TASK, + QDSP_MODULE_AUDPLAY3TASK, + QDSP_MODULE_AUDPLAY4TASK, + QDSP_MODULE_GRAPHICSTASK, + QDSP_MODULE_MIDI, + QDSP_MODULE_GAUDIO, + QDSP_MODULE_VDEC_LP_MODE, + QDSP_MODULE_MAX, +} qdsp_module_type; + +#define QDSP_RTOS_MAX_TASK_ID 19U + +/* Table of modules indexed by task ID for the GAUDIO image */ +static qdsp_module_type qdsp_gaudio_task_to_module_table[] = { + QDSP_MODULE_KERNEL, + QDSP_MODULE_AFETASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_AUDPPTASK, + QDSP_MODULE_AUDPLAY0TASK, + QDSP_MODULE_AUDPLAY1TASK, + QDSP_MODULE_AUDPLAY2TASK, + QDSP_MODULE_AUDPLAY3TASK, + QDSP_MODULE_AUDPLAY4TASK, + QDSP_MODULE_MAX, + QDSP_MODULE_AUDRECTASK, + QDSP_MODULE_AUDPREPROCTASK, + QDSP_MODULE_MAX, + QDSP_MODULE_GRAPHICSTASK, + QDSP_MODULE_MAX +}; + +/* Queue offset table indexed by queue ID for the GAUDIO image */ +static uint32_t qdsp_gaudio_queue_offset_table[] = { + QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */ + 0x3be, /* QDSP_mpuAfeQueue */ + 0x3ee, /* QDSP_mpuGraphicsCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecPktQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */ + 0x3c2, /* QDSP_uPAudPPCmd1Queue */ + 0x3c6, /* QDSP_uPAudPPCmd2Queue */ + 0x3ca, /* QDSP_uPAudPPCmd3Queue */ + 0x3da, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ + 0x3de, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ + 0x3e2, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ + 0x3e6, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ + 0x3ea, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ + 0x3ce, /* QDSP_uPAudPreProcCmdQueue */ + 0x3d6, /* QDSP_uPAudRecBitStreamQueue */ + 0x3d2, /* QDSP_uPAudRecCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */ + QDSP_RTOS_NO_QUEUE /* QDSP_vfeCommandTableQueue */ +}; + +/* Table of modules indexed by task ID for the COMBO image */ +static qdsp_module_type qdsp_combo_task_to_module_table[] = { + QDSP_MODULE_KERNEL, + QDSP_MODULE_AFETASK, + QDSP_MODULE_VOCDECTASK, + QDSP_MODULE_VOCENCTASK, + QDSP_MODULE_VIDEOTASK, + QDSP_MODULE_VIDEOENCTASK, + QDSP_MODULE_VOICEPROCTASK, + QDSP_MODULE_VFETASK, + QDSP_MODULE_JPEGTASK, + QDSP_MODULE_AUDPPTASK, + QDSP_MODULE_AUDPLAY0TASK, + QDSP_MODULE_AUDPLAY1TASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_LPMTASK, + QDSP_MODULE_AUDRECTASK, + QDSP_MODULE_AUDPREPROCTASK, + QDSP_MODULE_MODMATHTASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX +}; + +/* Queue offset table indexed by queue ID for the COMBO image */ +static uint32_t qdsp_combo_queue_offset_table[] = { + 0x585, /* QDSP_lpmCommandQueue */ + 0x52d, /* QDSP_mpuAfeQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */ + 0x541, /* QDSP_mpuModmathCmdQueue */ + 0x555, /* QDSP_mpuVDecCmdQueue */ + 0x559, /* QDSP_mpuVDecPktQueue */ + 0x551, /* QDSP_mpuVEncCmdQueue */ + 0x535, /* QDSP_rxMpuDecCmdQueue */ + 0x539, /* QDSP_rxMpuDecPktQueue */ + 0x53d, /* QDSP_txMpuEncQueue */ + 0x55d, /* QDSP_uPAudPPCmd1Queue */ + 0x561, /* QDSP_uPAudPPCmd2Queue */ + 0x565, /* QDSP_uPAudPPCmd3Queue */ + 0x575, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ + 0x579, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ + 0x569, /* QDSP_uPAudPreProcCmdQueue */ + 0x571, /* QDSP_uPAudRecBitStreamQueue */ + 0x56d, /* QDSP_uPAudRecCmdQueue */ + 0x581, /* QDSP_uPJpegActionCmdQueue */ + 0x57d, /* QDSP_uPJpegCfgCmdQueue */ + 0x531, /* QDSP_uPVocProcQueue */ + 0x545, /* QDSP_vfeCommandQueue */ + 0x54d, /* QDSP_vfeCommandScaleQueue */ + 0x549 /* QDSP_vfeCommandTableQueue */ +}; + +/* Table of modules indexed by task ID for the QTV_LP image */ +static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = { + QDSP_MODULE_KERNEL, + QDSP_MODULE_AFETASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_VIDEOTASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_AUDPPTASK, + QDSP_MODULE_AUDPLAY0TASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_AUDRECTASK, + QDSP_MODULE_AUDPREPROCTASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX +}; + +/* Queue offset table indexed by queue ID for the QTV_LP image */ +static uint32_t qdsp_qtv_lp_queue_offset_table[] = { + QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */ + 0x40c, /* QDSP_mpuAfeQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */ + 0x410, /* QDSP_mpuVDecCmdQueue */ + 0x414, /* QDSP_mpuVDecPktQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */ + 0x41c, /* QDSP_uPAudPPCmd1Queue */ + 0x420, /* QDSP_uPAudPPCmd2Queue */ + 0x424, /* QDSP_uPAudPPCmd3Queue */ + 0x430, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ + 0x418, /* QDSP_uPAudPreProcCmdQueue */ + 0x42c, /* QDSP_uPAudRecBitStreamQueue */ + 0x428, /* QDSP_uPAudRecCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */ + QDSP_RTOS_NO_QUEUE /* QDSP_vfeCommandTableQueue */ +}; + +/* Tables to convert tasks to modules */ +static uint32_t *qdsp_task_to_module[] = { + qdsp_combo_task_to_module_table, + qdsp_gaudio_task_to_module_table, + qdsp_qtv_lp_task_to_module_table, +}; + +/* Tables to retrieve queue offsets */ +static uint32_t *qdsp_queue_offset_table[] = { + qdsp_combo_queue_offset_table, + qdsp_gaudio_queue_offset_table, + qdsp_qtv_lp_queue_offset_table, +}; + +#define QDSP_MODULE(n) \ + { .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n } + +static struct adsp_module_info module_info[] = { + QDSP_MODULE(AUDPPTASK), + QDSP_MODULE(AUDRECTASK), + QDSP_MODULE(AUDPREPROCTASK), + QDSP_MODULE(VFETASK), + QDSP_MODULE(QCAMTASK), + QDSP_MODULE(LPMTASK), + QDSP_MODULE(JPEGTASK), + QDSP_MODULE(VIDEOTASK), + QDSP_MODULE(VDEC_LP_MODE), +}; + +int adsp_init_info(struct adsp_info *info) +{ + info->send_irq = 0x00c00200; + info->read_ctrl = 0x00400038; + info->write_ctrl = 0x00400034; + + info->max_msg16_size = 193; + info->max_msg32_size = 8; + + info->max_task_id = 16; + info->max_module_id = QDSP_MODULE_MAX - 1; + info->max_queue_id = QDSP_QUEUE_MAX; + info->max_image_id = 2; + info->queue_offset = qdsp_queue_offset_table; + info->task_to_module = qdsp_task_to_module; + + info->module_count = ARRAY_SIZE(module_info); + info->module = module_info; + return 0; +} diff --git a/trunk/drivers/staging/dream/qdsp5/adsp_6220.c b/trunk/drivers/staging/dream/qdsp5/adsp_6220.c new file mode 100644 index 000000000000..02225cd7ec8f --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/adsp_6220.c @@ -0,0 +1,284 @@ +/* arch/arm/mach-msm/qdsp5/adsp_6220.h + * + * Copyright (c) 2008 QUALCOMM Incorporated. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "adsp.h" + +/* Firmware modules */ +typedef enum { + QDSP_MODULE_KERNEL, + QDSP_MODULE_AFETASK, + QDSP_MODULE_AUDPLAY0TASK, + QDSP_MODULE_AUDPLAY1TASK, + QDSP_MODULE_AUDPPTASK, + QDSP_MODULE_VIDEOTASK, + QDSP_MODULE_VIDEO_AAC_VOC, + QDSP_MODULE_PCM_DEC, + QDSP_MODULE_AUDIO_DEC_MP3, + QDSP_MODULE_AUDIO_DEC_AAC, + QDSP_MODULE_AUDIO_DEC_WMA, + QDSP_MODULE_HOSTPCM, + QDSP_MODULE_DTMF, + QDSP_MODULE_AUDRECTASK, + QDSP_MODULE_AUDPREPROCTASK, + QDSP_MODULE_SBC_ENC, + QDSP_MODULE_VOC, + QDSP_MODULE_VOC_PCM, + QDSP_MODULE_VOCENCTASK, + QDSP_MODULE_VOCDECTASK, + QDSP_MODULE_VOICEPROCTASK, + QDSP_MODULE_VIDEOENCTASK, + QDSP_MODULE_VFETASK, + QDSP_MODULE_WAV_ENC, + QDSP_MODULE_AACLC_ENC, + QDSP_MODULE_VIDEO_AMR, + QDSP_MODULE_VOC_AMR, + QDSP_MODULE_VOC_EVRC, + QDSP_MODULE_VOC_13K, + QDSP_MODULE_VOC_FGV, + QDSP_MODULE_DIAGTASK, + QDSP_MODULE_JPEGTASK, + QDSP_MODULE_LPMTASK, + QDSP_MODULE_QCAMTASK, + QDSP_MODULE_MODMATHTASK, + QDSP_MODULE_AUDPLAY2TASK, + QDSP_MODULE_AUDPLAY3TASK, + QDSP_MODULE_AUDPLAY4TASK, + QDSP_MODULE_GRAPHICSTASK, + QDSP_MODULE_MIDI, + QDSP_MODULE_GAUDIO, + QDSP_MODULE_VDEC_LP_MODE, + QDSP_MODULE_MAX, +} qdsp_module_type; + +#define QDSP_RTOS_MAX_TASK_ID 19U + +/* Table of modules indexed by task ID for the GAUDIO image */ +static qdsp_module_type qdsp_gaudio_task_to_module_table[] = { + QDSP_MODULE_KERNEL, + QDSP_MODULE_AFETASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_AUDPPTASK, + QDSP_MODULE_AUDPLAY0TASK, + QDSP_MODULE_AUDPLAY1TASK, + QDSP_MODULE_AUDPLAY2TASK, + QDSP_MODULE_AUDPLAY3TASK, + QDSP_MODULE_AUDPLAY4TASK, + QDSP_MODULE_MAX, + QDSP_MODULE_AUDRECTASK, + QDSP_MODULE_AUDPREPROCTASK, + QDSP_MODULE_MAX, + QDSP_MODULE_GRAPHICSTASK, + QDSP_MODULE_MAX +}; + +/* Queue offset table indexed by queue ID for the GAUDIO image */ +static uint32_t qdsp_gaudio_queue_offset_table[] = { + QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */ + 0x3f0, /* QDSP_mpuAfeQueue */ + 0x420, /* QDSP_mpuGraphicsCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecPktQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */ + 0x3f4, /* QDSP_uPAudPPCmd1Queue */ + 0x3f8, /* QDSP_uPAudPPCmd2Queue */ + 0x3fc, /* QDSP_uPAudPPCmd3Queue */ + 0x40c, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ + 0x410, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ + 0x414, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ + 0x418, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ + 0x41c, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ + 0x400, /* QDSP_uPAudPreProcCmdQueue */ + 0x408, /* QDSP_uPAudRecBitStreamQueue */ + 0x404, /* QDSP_uPAudRecCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */ + QDSP_RTOS_NO_QUEUE /* QDSP_vfeCommandTableQueue */ +}; + +/* Table of modules indexed by task ID for the COMBO image */ +static qdsp_module_type qdsp_combo_task_to_module_table[] = { + QDSP_MODULE_KERNEL, + QDSP_MODULE_AFETASK, + QDSP_MODULE_VOCDECTASK, + QDSP_MODULE_VOCENCTASK, + QDSP_MODULE_VIDEOTASK, + QDSP_MODULE_VIDEOENCTASK, + QDSP_MODULE_VOICEPROCTASK, + QDSP_MODULE_VFETASK, + QDSP_MODULE_JPEGTASK, + QDSP_MODULE_AUDPPTASK, + QDSP_MODULE_AUDPLAY0TASK, + QDSP_MODULE_AUDPLAY1TASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_LPMTASK, + QDSP_MODULE_AUDRECTASK, + QDSP_MODULE_AUDPREPROCTASK, + QDSP_MODULE_MODMATHTASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX +}; + +/* Queue offset table indexed by queue ID for the COMBO image */ +static uint32_t qdsp_combo_queue_offset_table[] = { + 0x6f2, /* QDSP_lpmCommandQueue */ + 0x69e, /* QDSP_mpuAfeQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */ + 0x6b2, /* QDSP_mpuModmathCmdQueue */ + 0x6c6, /* QDSP_mpuVDecCmdQueue */ + 0x6ca, /* QDSP_mpuVDecPktQueue */ + 0x6c2, /* QDSP_mpuVEncCmdQueue */ + 0x6a6, /* QDSP_rxMpuDecCmdQueue */ + 0x6aa, /* QDSP_rxMpuDecPktQueue */ + 0x6ae, /* QDSP_txMpuEncQueue */ + 0x6ce, /* QDSP_uPAudPPCmd1Queue */ + 0x6d2, /* QDSP_uPAudPPCmd2Queue */ + 0x6d6, /* QDSP_uPAudPPCmd3Queue */ + 0x6e6, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ + 0x6da, /* QDSP_uPAudPreProcCmdQueue */ + 0x6e2, /* QDSP_uPAudRecBitStreamQueue */ + 0x6de, /* QDSP_uPAudRecCmdQueue */ + 0x6ee, /* QDSP_uPJpegActionCmdQueue */ + 0x6ea, /* QDSP_uPJpegCfgCmdQueue */ + 0x6a2, /* QDSP_uPVocProcQueue */ + 0x6b6, /* QDSP_vfeCommandQueue */ + 0x6be, /* QDSP_vfeCommandScaleQueue */ + 0x6ba /* QDSP_vfeCommandTableQueue */ +}; + +/* Table of modules indexed by task ID for the QTV_LP image */ +static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = { + QDSP_MODULE_KERNEL, + QDSP_MODULE_AFETASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_VIDEOTASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_AUDPPTASK, + QDSP_MODULE_AUDPLAY0TASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_AUDRECTASK, + QDSP_MODULE_AUDPREPROCTASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX +}; + +/* Queue offset table indexed by queue ID for the QTV_LP image */ +static uint32_t qdsp_qtv_lp_queue_offset_table[] = { + QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */ + 0x430, /* QDSP_mpuAfeQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */ + 0x434, /* QDSP_mpuVDecCmdQueue */ + 0x438, /* QDSP_mpuVDecPktQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */ + 0x440, /* QDSP_uPAudPPCmd1Queue */ + 0x444, /* QDSP_uPAudPPCmd2Queue */ + 0x448, /* QDSP_uPAudPPCmd3Queue */ + 0x454, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ + 0x43c, /* QDSP_uPAudPreProcCmdQueue */ + 0x450, /* QDSP_uPAudRecBitStreamQueue */ + 0x44c, /* QDSP_uPAudRecCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */ + QDSP_RTOS_NO_QUEUE /* QDSP_vfeCommandTableQueue */ +}; + +/* Tables to convert tasks to modules */ +static qdsp_module_type *qdsp_task_to_module[] = { + qdsp_combo_task_to_module_table, + qdsp_gaudio_task_to_module_table, + qdsp_qtv_lp_task_to_module_table, +}; + +/* Tables to retrieve queue offsets */ +static uint32_t *qdsp_queue_offset_table[] = { + qdsp_combo_queue_offset_table, + qdsp_gaudio_queue_offset_table, + qdsp_qtv_lp_queue_offset_table, +}; + +#define QDSP_MODULE(n) \ + { .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n } + +static struct adsp_module_info module_info[] = { + QDSP_MODULE(AUDPLAY0TASK), + QDSP_MODULE(AUDPPTASK), + QDSP_MODULE(AUDPREPROCTASK), + QDSP_MODULE(AUDRECTASK), + QDSP_MODULE(VFETASK), + QDSP_MODULE(QCAMTASK), + QDSP_MODULE(LPMTASK), + QDSP_MODULE(JPEGTASK), + QDSP_MODULE(VIDEOTASK), + QDSP_MODULE(VDEC_LP_MODE), +}; + +int adsp_init_info(struct adsp_info *info) +{ + info->send_irq = 0x00c00200; + info->read_ctrl = 0x00400038; + info->write_ctrl = 0x00400034; + + info->max_msg16_size = 193; + info->max_msg32_size = 8; + + info->max_task_id = 16; + info->max_module_id = QDSP_MODULE_MAX - 1; + info->max_queue_id = QDSP_QUEUE_MAX; + info->max_image_id = 2; + info->queue_offset = qdsp_queue_offset_table; + info->task_to_module = qdsp_task_to_module; + + info->module_count = ARRAY_SIZE(module_info); + info->module = module_info; + return 0; +} diff --git a/trunk/drivers/staging/dream/qdsp5/adsp_6225.c b/trunk/drivers/staging/dream/qdsp5/adsp_6225.c new file mode 100644 index 000000000000..5078afbb1a8c --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/adsp_6225.c @@ -0,0 +1,328 @@ +/* arch/arm/mach-msm/qdsp5/adsp_6225.h + * + * Copyright (c) 2008 QUALCOMM Incorporated. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "adsp.h" + +/* Firmware modules */ +typedef enum { + QDSP_MODULE_KERNEL, + QDSP_MODULE_AFETASK, + QDSP_MODULE_AUDPLAY0TASK, + QDSP_MODULE_AUDPLAY1TASK, + QDSP_MODULE_AUDPPTASK, + QDSP_MODULE_VIDEOTASK, + QDSP_MODULE_VIDEO_AAC_VOC, + QDSP_MODULE_PCM_DEC, + QDSP_MODULE_AUDIO_DEC_MP3, + QDSP_MODULE_AUDIO_DEC_AAC, + QDSP_MODULE_AUDIO_DEC_WMA, + QDSP_MODULE_HOSTPCM, + QDSP_MODULE_DTMF, + QDSP_MODULE_AUDRECTASK, + QDSP_MODULE_AUDPREPROCTASK, + QDSP_MODULE_SBC_ENC, + QDSP_MODULE_VOC_UMTS, + QDSP_MODULE_VOC_CDMA, + QDSP_MODULE_VOC_PCM, + QDSP_MODULE_VOCENCTASK, + QDSP_MODULE_VOCDECTASK, + QDSP_MODULE_VOICEPROCTASK, + QDSP_MODULE_VIDEOENCTASK, + QDSP_MODULE_VFETASK, + QDSP_MODULE_WAV_ENC, + QDSP_MODULE_AACLC_ENC, + QDSP_MODULE_VIDEO_AMR, + QDSP_MODULE_VOC_AMR, + QDSP_MODULE_VOC_EVRC, + QDSP_MODULE_VOC_13K, + QDSP_MODULE_VOC_FGV, + QDSP_MODULE_DIAGTASK, + QDSP_MODULE_JPEGTASK, + QDSP_MODULE_LPMTASK, + QDSP_MODULE_QCAMTASK, + QDSP_MODULE_MODMATHTASK, + QDSP_MODULE_AUDPLAY2TASK, + QDSP_MODULE_AUDPLAY3TASK, + QDSP_MODULE_AUDPLAY4TASK, + QDSP_MODULE_GRAPHICSTASK, + QDSP_MODULE_MIDI, + QDSP_MODULE_GAUDIO, + QDSP_MODULE_VDEC_LP_MODE, + QDSP_MODULE_MAX, +} qdsp_module_type; + +#define QDSP_RTOS_MAX_TASK_ID 30U + +/* Table of modules indexed by task ID for the GAUDIO image */ +static qdsp_module_type qdsp_gaudio_task_to_module_table[] = { + QDSP_MODULE_KERNEL, + QDSP_MODULE_AFETASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_AUDPPTASK, + QDSP_MODULE_AUDPLAY0TASK, + QDSP_MODULE_AUDPLAY1TASK, + QDSP_MODULE_AUDPLAY2TASK, + QDSP_MODULE_AUDPLAY3TASK, + QDSP_MODULE_AUDPLAY4TASK, + QDSP_MODULE_MAX, + QDSP_MODULE_AUDRECTASK, + QDSP_MODULE_AUDPREPROCTASK, + QDSP_MODULE_MAX, + QDSP_MODULE_GRAPHICSTASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, +}; + +/* Queue offset table indexed by queue ID for the GAUDIO image */ +static uint32_t qdsp_gaudio_queue_offset_table[] = { + QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */ + 0x3f0, /* QDSP_mpuAfeQueue */ + 0x420, /* QDSP_mpuGraphicsCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecPktQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */ + 0x3f4, /* QDSP_uPAudPPCmd1Queue */ + 0x3f8, /* QDSP_uPAudPPCmd2Queue */ + 0x3fc, /* QDSP_uPAudPPCmd3Queue */ + 0x40c, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ + 0x410, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ + 0x414, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ + 0x418, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ + 0x41c, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ + 0x400, /* QDSP_uPAudPreProcCmdQueue */ + 0x408, /* QDSP_uPAudRecBitStreamQueue */ + 0x404, /* QDSP_uPAudRecCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandTableQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPDiagQueue */ +}; + +/* Table of modules indexed by task ID for the COMBO image */ +static qdsp_module_type qdsp_combo_task_to_module_table[] = { + QDSP_MODULE_KERNEL, + QDSP_MODULE_AFETASK, + QDSP_MODULE_VOCDECTASK, + QDSP_MODULE_VOCENCTASK, + QDSP_MODULE_VIDEOTASK, + QDSP_MODULE_VIDEOENCTASK, + QDSP_MODULE_VOICEPROCTASK, + QDSP_MODULE_VFETASK, + QDSP_MODULE_JPEGTASK, + QDSP_MODULE_AUDPPTASK, + QDSP_MODULE_AUDPLAY0TASK, + QDSP_MODULE_AUDPLAY1TASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_LPMTASK, + QDSP_MODULE_AUDRECTASK, + QDSP_MODULE_AUDPREPROCTASK, + QDSP_MODULE_MODMATHTASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_DIAGTASK, + QDSP_MODULE_MAX, +}; + +/* Queue offset table indexed by queue ID for the COMBO image */ +static uint32_t qdsp_combo_queue_offset_table[] = { + 0x714, /* QDSP_lpmCommandQueue */ + 0x6bc, /* QDSP_mpuAfeQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */ + 0x6d0, /* QDSP_mpuModmathCmdQueue */ + 0x6e8, /* QDSP_mpuVDecCmdQueue */ + 0x6ec, /* QDSP_mpuVDecPktQueue */ + 0x6e4, /* QDSP_mpuVEncCmdQueue */ + 0x6c4, /* QDSP_rxMpuDecCmdQueue */ + 0x6c8, /* QDSP_rxMpuDecPktQueue */ + 0x6cc, /* QDSP_txMpuEncQueue */ + 0x6f0, /* QDSP_uPAudPPCmd1Queue */ + 0x6f4, /* QDSP_uPAudPPCmd2Queue */ + 0x6f8, /* QDSP_uPAudPPCmd3Queue */ + 0x708, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ + 0x6fc, /* QDSP_uPAudPreProcCmdQueue */ + 0x704, /* QDSP_uPAudRecBitStreamQueue */ + 0x700, /* QDSP_uPAudRecCmdQueue */ + 0x710, /* QDSP_uPJpegActionCmdQueue */ + 0x70c, /* QDSP_uPJpegCfgCmdQueue */ + 0x6c0, /* QDSP_uPVocProcQueue */ + 0x6d8, /* QDSP_vfeCommandQueue */ + 0x6e0, /* QDSP_vfeCommandScaleQueue */ + 0x6dc, /* QDSP_vfeCommandTableQueue */ + 0x6d4, /* QDSP_uPDiagQueue */ +}; + +/* Table of modules indexed by task ID for the QTV_LP image */ +static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = { + QDSP_MODULE_KERNEL, + QDSP_MODULE_AFETASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_VIDEOTASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_AUDPPTASK, + QDSP_MODULE_AUDPLAY0TASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_AUDRECTASK, + QDSP_MODULE_AUDPREPROCTASK, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, + QDSP_MODULE_MAX, +}; + +/* Queue offset table indexed by queue ID for the QTV_LP image */ +static uint32_t qdsp_qtv_lp_queue_offset_table[] = { + QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */ + 0x3fe, /* QDSP_mpuAfeQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */ + 0x402, /* QDSP_mpuVDecCmdQueue */ + 0x406, /* QDSP_mpuVDecPktQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */ + 0x40e, /* QDSP_uPAudPPCmd1Queue */ + 0x412, /* QDSP_uPAudPPCmd2Queue */ + 0x416, /* QDSP_uPAudPPCmd3Queue */ + 0x422, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ + 0x40a, /* QDSP_uPAudPreProcCmdQueue */ + 0x41e, /* QDSP_uPAudRecBitStreamQueue */ + 0x41a, /* QDSP_uPAudRecCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandTableQueue */ + QDSP_RTOS_NO_QUEUE, /* QDSP_uPDiagQueue */ +}; + +/* Tables to convert tasks to modules */ +static qdsp_module_type *qdsp_task_to_module[] = { + qdsp_combo_task_to_module_table, + qdsp_gaudio_task_to_module_table, + qdsp_qtv_lp_task_to_module_table, +}; + +/* Tables to retrieve queue offsets */ +static uint32_t *qdsp_queue_offset_table[] = { + qdsp_combo_queue_offset_table, + qdsp_gaudio_queue_offset_table, + qdsp_qtv_lp_queue_offset_table, +}; + +#define QDSP_MODULE(n, clkname, clkrate, verify_cmd_func, patch_event_func) \ + { .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n, \ + .clk_name = clkname, .clk_rate = clkrate, \ + .verify_cmd = verify_cmd_func, .patch_event = patch_event_func } + +static struct adsp_module_info module_info[] = { + QDSP_MODULE(AUDPLAY0TASK, NULL, 0, NULL, NULL), + QDSP_MODULE(AUDPPTASK, NULL, 0, NULL, NULL), + QDSP_MODULE(AUDRECTASK, NULL, 0, NULL, NULL), + QDSP_MODULE(AUDPREPROCTASK, NULL, 0, NULL, NULL), + QDSP_MODULE(VFETASK, "vfe_clk", 0, adsp_vfe_verify_cmd, + adsp_vfe_patch_event), + QDSP_MODULE(QCAMTASK, NULL, 0, NULL, NULL), + QDSP_MODULE(LPMTASK, NULL, 0, adsp_lpm_verify_cmd, NULL), + QDSP_MODULE(JPEGTASK, "vdc_clk", 0, adsp_jpeg_verify_cmd, + adsp_jpeg_patch_event), + QDSP_MODULE(VIDEOTASK, "vdc_clk", 96000000, + adsp_video_verify_cmd, NULL), + QDSP_MODULE(VDEC_LP_MODE, NULL, 0, NULL, NULL), + QDSP_MODULE(VIDEOENCTASK, "vdc_clk", 96000000, + adsp_videoenc_verify_cmd, NULL), +}; + +int adsp_init_info(struct adsp_info *info) +{ + info->send_irq = 0x00c00200; + info->read_ctrl = 0x00400038; + info->write_ctrl = 0x00400034; + + info->max_msg16_size = 193; + info->max_msg32_size = 8; + + info->max_task_id = 16; + info->max_module_id = QDSP_MODULE_MAX - 1; + info->max_queue_id = QDSP_QUEUE_MAX; + info->max_image_id = 2; + info->queue_offset = qdsp_queue_offset_table; + info->task_to_module = qdsp_task_to_module; + + info->module_count = ARRAY_SIZE(module_info); + info->module = module_info; + return 0; +} diff --git a/trunk/drivers/staging/dream/qdsp5/adsp_driver.c b/trunk/drivers/staging/dream/qdsp5/adsp_driver.c new file mode 100644 index 000000000000..28a6f8da9477 --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/adsp_driver.c @@ -0,0 +1,643 @@ +/* arch/arm/mach-msm/qdsp5/adsp_driver.c + * + * Copyright (C) 2008 Google, Inc. + * Author: Iliyan Malchev + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "adsp.h" + +#include +#include + +struct adsp_pmem_region { + struct hlist_node list; + void *vaddr; + unsigned long paddr; + unsigned long kvaddr; + unsigned long len; + struct file *file; +}; + +struct adsp_device { + struct msm_adsp_module *module; + + spinlock_t event_queue_lock; + wait_queue_head_t event_wait; + struct list_head event_queue; + int abort; + + const char *name; + struct device *device; + struct cdev cdev; +}; + +static struct adsp_device *inode_to_device(struct inode *inode); + +#define __CONTAINS(r, v, l) ({ \ + typeof(r) __r = r; \ + typeof(v) __v = v; \ + typeof(v) __e = __v + l; \ + int res = __v >= __r->vaddr && \ + __e <= __r->vaddr + __r->len; \ + res; \ +}) + +#define CONTAINS(r1, r2) ({ \ + typeof(r2) __r2 = r2; \ + __CONTAINS(r1, __r2->vaddr, __r2->len); \ +}) + +#define IN_RANGE(r, v) ({ \ + typeof(r) __r = r; \ + typeof(v) __vv = v; \ + int res = ((__vv >= __r->vaddr) && \ + (__vv < (__r->vaddr + __r->len))); \ + res; \ +}) + +#define OVERLAPS(r1, r2) ({ \ + typeof(r1) __r1 = r1; \ + typeof(r2) __r2 = r2; \ + typeof(__r2->vaddr) __v = __r2->vaddr; \ + typeof(__v) __e = __v + __r2->len - 1; \ + int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e)); \ + res; \ +}) + +static int adsp_pmem_check(struct msm_adsp_module *module, + void *vaddr, unsigned long len) +{ + struct adsp_pmem_region *region_elt; + struct hlist_node *node; + struct adsp_pmem_region t = { .vaddr = vaddr, .len = len }; + + hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) { + if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) || + OVERLAPS(region_elt, &t)) { + printk(KERN_ERR "adsp: module %s:" + " region (vaddr %p len %ld)" + " clashes with registered region" + " (vaddr %p paddr %p len %ld)\n", + module->name, + vaddr, len, + region_elt->vaddr, + (void *)region_elt->paddr, + region_elt->len); + return -EINVAL; + } + } + + return 0; +} + +static int adsp_pmem_add(struct msm_adsp_module *module, + struct adsp_pmem_info *info) +{ + unsigned long paddr, kvaddr, len; + struct file *file; + struct adsp_pmem_region *region; + int rc = -EINVAL; + + mutex_lock(&module->pmem_regions_lock); + region = kmalloc(sizeof(*region), GFP_KERNEL); + if (!region) { + rc = -ENOMEM; + goto end; + } + INIT_HLIST_NODE(®ion->list); + if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) { + kfree(region); + goto end; + } + + rc = adsp_pmem_check(module, info->vaddr, len); + if (rc < 0) { + put_pmem_file(file); + kfree(region); + goto end; + } + + region->vaddr = info->vaddr; + region->paddr = paddr; + region->kvaddr = kvaddr; + region->len = len; + region->file = file; + + hlist_add_head(®ion->list, &module->pmem_regions); +end: + mutex_unlock(&module->pmem_regions_lock); + return rc; +} + +static int adsp_pmem_lookup_vaddr(struct msm_adsp_module *module, void **addr, + unsigned long len, struct adsp_pmem_region **region) +{ + struct hlist_node *node; + void *vaddr = *addr; + struct adsp_pmem_region *region_elt; + + int match_count = 0; + + *region = NULL; + + /* returns physical address or zero */ + hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) { + if (vaddr >= region_elt->vaddr && + vaddr < region_elt->vaddr + region_elt->len && + vaddr + len <= region_elt->vaddr + region_elt->len) { + /* offset since we could pass vaddr inside a registerd + * pmem buffer + */ + + match_count++; + if (!*region) + *region = region_elt; + } + } + + if (match_count > 1) { + printk(KERN_ERR "adsp: module %s: " + "multiple hits for vaddr %p, len %ld\n", + module->name, vaddr, len); + hlist_for_each_entry(region_elt, node, + &module->pmem_regions, list) { + if (vaddr >= region_elt->vaddr && + vaddr < region_elt->vaddr + region_elt->len && + vaddr + len <= region_elt->vaddr + region_elt->len) + printk(KERN_ERR "\t%p, %ld --> %p\n", + region_elt->vaddr, + region_elt->len, + (void *)region_elt->paddr); + } + } + + return *region ? 0 : -1; +} + +int adsp_pmem_fixup_kvaddr(struct msm_adsp_module *module, void **addr, + unsigned long *kvaddr, unsigned long len) +{ + struct adsp_pmem_region *region; + void *vaddr = *addr; + unsigned long *paddr = (unsigned long *)addr; + int ret; + + ret = adsp_pmem_lookup_vaddr(module, addr, len, ®ion); + if (ret) { + printk(KERN_ERR "adsp: not patching %s (paddr & kvaddr)," + " lookup (%p, %ld) failed\n", + module->name, vaddr, len); + return ret; + } + *paddr = region->paddr + (vaddr - region->vaddr); + *kvaddr = region->kvaddr + (vaddr - region->vaddr); + return 0; +} + +int adsp_pmem_fixup(struct msm_adsp_module *module, void **addr, + unsigned long len) +{ + struct adsp_pmem_region *region; + void *vaddr = *addr; + unsigned long *paddr = (unsigned long *)addr; + int ret; + + ret = adsp_pmem_lookup_vaddr(module, addr, len, ®ion); + if (ret) { + printk(KERN_ERR "adsp: not patching %s, lookup (%p, %ld) failed\n", + module->name, vaddr, len); + return ret; + } + + *paddr = region->paddr + (vaddr - region->vaddr); + return 0; +} + +static int adsp_verify_cmd(struct msm_adsp_module *module, + unsigned int queue_id, void *cmd_data, + size_t cmd_size) +{ + /* call the per module verifier */ + if (module->verify_cmd) + return module->verify_cmd(module, queue_id, cmd_data, + cmd_size); + else + printk(KERN_INFO "adsp: no packet verifying function " + "for task %s\n", module->name); + return 0; +} + +static long adsp_write_cmd(struct adsp_device *adev, void __user *arg) +{ + struct adsp_command_t cmd; + unsigned char buf[256]; + void *cmd_data; + long rc; + + if (copy_from_user(&cmd, (void __user *)arg, sizeof(cmd))) + return -EFAULT; + + if (cmd.len > 256) { + cmd_data = kmalloc(cmd.len, GFP_USER); + if (!cmd_data) + return -ENOMEM; + } else { + cmd_data = buf; + } + + if (copy_from_user(cmd_data, (void __user *)(cmd.data), cmd.len)) { + rc = -EFAULT; + goto end; + } + + mutex_lock(&adev->module->pmem_regions_lock); + if (adsp_verify_cmd(adev->module, cmd.queue, cmd_data, cmd.len)) { + printk(KERN_ERR "module %s: verify failed.\n", + adev->module->name); + rc = -EINVAL; + goto end; + } + rc = msm_adsp_write(adev->module, cmd.queue, cmd_data, cmd.len); +end: + mutex_unlock(&adev->module->pmem_regions_lock); + + if (cmd.len > 256) + kfree(cmd_data); + + return rc; +} + +static int adsp_events_pending(struct adsp_device *adev) +{ + unsigned long flags; + int yes; + spin_lock_irqsave(&adev->event_queue_lock, flags); + yes = !list_empty(&adev->event_queue); + spin_unlock_irqrestore(&adev->event_queue_lock, flags); + return yes || adev->abort; +} + +static int adsp_pmem_lookup_paddr(struct msm_adsp_module *module, void **addr, + struct adsp_pmem_region **region) +{ + struct hlist_node *node; + unsigned long paddr = (unsigned long)(*addr); + struct adsp_pmem_region *region_elt; + + hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) { + if (paddr >= region_elt->paddr && + paddr < region_elt->paddr + region_elt->len) { + *region = region_elt; + return 0; + } + } + return -1; +} + +int adsp_pmem_paddr_fixup(struct msm_adsp_module *module, void **addr) +{ + struct adsp_pmem_region *region; + unsigned long paddr = (unsigned long)(*addr); + unsigned long *vaddr = (unsigned long *)addr; + int ret; + + ret = adsp_pmem_lookup_paddr(module, addr, ®ion); + if (ret) { + printk(KERN_ERR "adsp: not patching %s, paddr %p lookup failed\n", + module->name, vaddr); + return ret; + } + + *vaddr = (unsigned long)region->vaddr + (paddr - region->paddr); + return 0; +} + +static int adsp_patch_event(struct msm_adsp_module *module, + struct adsp_event *event) +{ + /* call the per-module msg verifier */ + if (module->patch_event) + return module->patch_event(module, event); + return 0; +} + +static long adsp_get_event(struct adsp_device *adev, void __user *arg) +{ + unsigned long flags; + struct adsp_event *data = NULL; + struct adsp_event_t evt; + int timeout; + long rc = 0; + + if (copy_from_user(&evt, arg, sizeof(struct adsp_event_t))) + return -EFAULT; + + timeout = (int)evt.timeout_ms; + + if (timeout > 0) { + rc = wait_event_interruptible_timeout( + adev->event_wait, adsp_events_pending(adev), + msecs_to_jiffies(timeout)); + if (rc == 0) + return -ETIMEDOUT; + } else { + rc = wait_event_interruptible( + adev->event_wait, adsp_events_pending(adev)); + } + if (rc < 0) + return rc; + + if (adev->abort) + return -ENODEV; + + spin_lock_irqsave(&adev->event_queue_lock, flags); + if (!list_empty(&adev->event_queue)) { + data = list_first_entry(&adev->event_queue, + struct adsp_event, list); + list_del(&data->list); + } + spin_unlock_irqrestore(&adev->event_queue_lock, flags); + + if (!data) + return -EAGAIN; + + /* DSP messages are type 0; they may contain physical addresses */ + if (data->type == 0) + adsp_patch_event(adev->module, data); + + /* map adsp_event --> adsp_event_t */ + if (evt.len < data->size) { + rc = -ETOOSMALL; + goto end; + } + if (data->msg_id != EVENT_MSG_ID) { + if (copy_to_user((void *)(evt.data), data->data.msg16, + data->size)) { + rc = -EFAULT; + goto end; + } + } else { + if (copy_to_user((void *)(evt.data), data->data.msg32, + data->size)) { + rc = -EFAULT; + goto end; + } + } + + evt.type = data->type; /* 0 --> from aDSP, 1 --> from ARM9 */ + evt.msg_id = data->msg_id; + evt.flags = data->is16; + evt.len = data->size; + if (copy_to_user(arg, &evt, sizeof(evt))) + rc = -EFAULT; +end: + kfree(data); + return rc; +} + +static long adsp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct adsp_device *adev = filp->private_data; + + switch (cmd) { + case ADSP_IOCTL_ENABLE: + return msm_adsp_enable(adev->module); + + case ADSP_IOCTL_DISABLE: + return msm_adsp_disable(adev->module); + + case ADSP_IOCTL_DISABLE_EVENT_RSP: + return 0; + + case ADSP_IOCTL_DISABLE_ACK: + pr_err("adsp: ADSP_IOCTL_DISABLE_ACK is not implemented.\n"); + break; + + case ADSP_IOCTL_WRITE_COMMAND: + return adsp_write_cmd(adev, (void __user *) arg); + + case ADSP_IOCTL_GET_EVENT: + return adsp_get_event(adev, (void __user *) arg); + + case ADSP_IOCTL_SET_CLKRATE: { +#if CONFIG_MSM_AMSS_VERSION==6350 + unsigned long clk_rate; + if (copy_from_user(&clk_rate, (void *) arg, sizeof(clk_rate))) + return -EFAULT; + return adsp_set_clkrate(adev->module, clk_rate); +#endif + } + + case ADSP_IOCTL_REGISTER_PMEM: { + struct adsp_pmem_info info; + if (copy_from_user(&info, (void *) arg, sizeof(info))) + return -EFAULT; + return adsp_pmem_add(adev->module, &info); + } + + case ADSP_IOCTL_ABORT_EVENT_READ: + adev->abort = 1; + wake_up(&adev->event_wait); + break; + + default: + break; + } + return -EINVAL; +} + +static int adsp_release(struct inode *inode, struct file *filp) +{ + struct adsp_device *adev = filp->private_data; + struct msm_adsp_module *module = adev->module; + struct hlist_node *node, *tmp; + struct adsp_pmem_region *region; + + pr_info("adsp_release() '%s'\n", adev->name); + + /* clear module before putting it to avoid race with open() */ + adev->module = NULL; + + mutex_lock(&module->pmem_regions_lock); + hlist_for_each_safe(node, tmp, &module->pmem_regions) { + region = hlist_entry(node, struct adsp_pmem_region, list); + hlist_del(node); + put_pmem_file(region->file); + kfree(region); + } + mutex_unlock(&module->pmem_regions_lock); + BUG_ON(!hlist_empty(&module->pmem_regions)); + + msm_adsp_put(module); + return 0; +} + +static void adsp_event(void *driver_data, unsigned id, size_t len, + void (*getevent)(void *ptr, size_t len)) +{ + struct adsp_device *adev = driver_data; + struct adsp_event *event; + unsigned long flags; + + if (len > ADSP_EVENT_MAX_SIZE) { + pr_err("adsp_event: event too large (%d bytes)\n", len); + return; + } + + event = kmalloc(sizeof(*event), GFP_ATOMIC); + if (!event) { + pr_err("adsp_event: cannot allocate buffer\n"); + return; + } + + if (id != EVENT_MSG_ID) { + event->type = 0; + event->is16 = 0; + event->msg_id = id; + event->size = len; + + getevent(event->data.msg16, len); + } else { + event->type = 1; + event->is16 = 1; + event->msg_id = id; + event->size = len; + getevent(event->data.msg32, len); + } + + spin_lock_irqsave(&adev->event_queue_lock, flags); + list_add_tail(&event->list, &adev->event_queue); + spin_unlock_irqrestore(&adev->event_queue_lock, flags); + wake_up(&adev->event_wait); +} + +static struct msm_adsp_ops adsp_ops = { + .event = adsp_event, +}; + +static int adsp_open(struct inode *inode, struct file *filp) +{ + struct adsp_device *adev; + int rc; + + rc = nonseekable_open(inode, filp); + if (rc < 0) + return rc; + + adev = inode_to_device(inode); + if (!adev) + return -ENODEV; + + pr_info("adsp_open() name = '%s'\n", adev->name); + + rc = msm_adsp_get(adev->name, &adev->module, &adsp_ops, adev); + if (rc) + return rc; + + pr_info("adsp_open() module '%s' adev %p\n", adev->name, adev); + filp->private_data = adev; + adev->abort = 0; + INIT_HLIST_HEAD(&adev->module->pmem_regions); + mutex_init(&adev->module->pmem_regions_lock); + + return 0; +} + +static unsigned adsp_device_count; +static struct adsp_device *adsp_devices; + +static struct adsp_device *inode_to_device(struct inode *inode) +{ + unsigned n = MINOR(inode->i_rdev); + if (n < adsp_device_count) { + if (adsp_devices[n].device) + return adsp_devices + n; + } + return NULL; +} + +static dev_t adsp_devno; +static struct class *adsp_class; + +static struct file_operations adsp_fops = { + .owner = THIS_MODULE, + .open = adsp_open, + .unlocked_ioctl = adsp_ioctl, + .release = adsp_release, + .llseek = no_llseek, +}; + +static void adsp_create(struct adsp_device *adev, const char *name, + struct device *parent, dev_t devt) +{ + struct device *dev; + int rc; + + dev = device_create(adsp_class, parent, devt, "%s", name); + if (IS_ERR(dev)) + return; + + init_waitqueue_head(&adev->event_wait); + INIT_LIST_HEAD(&adev->event_queue); + spin_lock_init(&adev->event_queue_lock); + + cdev_init(&adev->cdev, &adsp_fops); + adev->cdev.owner = THIS_MODULE; + + rc = cdev_add(&adev->cdev, devt, 1); + if (rc < 0) { + device_destroy(adsp_class, devt); + } else { + adev->device = dev; + adev->name = name; + } +} + +void msm_adsp_publish_cdevs(struct msm_adsp_module *modules, unsigned n) +{ + int rc; + + adsp_devices = kzalloc(sizeof(struct adsp_device) * n, GFP_KERNEL); + if (!adsp_devices) + return; + + adsp_class = class_create(THIS_MODULE, "adsp"); + if (IS_ERR(adsp_class)) + goto fail_create_class; + + rc = alloc_chrdev_region(&adsp_devno, 0, n, "adsp"); + if (rc < 0) + goto fail_alloc_region; + + adsp_device_count = n; + for (n = 0; n < adsp_device_count; n++) { + adsp_create(adsp_devices + n, + modules[n].name, &modules[n].pdev.dev, + MKDEV(MAJOR(adsp_devno), n)); + } + + return; + +fail_alloc_region: + class_unregister(adsp_class); +fail_create_class: + kfree(adsp_devices); +} diff --git a/trunk/drivers/staging/dream/qdsp5/adsp_info.c b/trunk/drivers/staging/dream/qdsp5/adsp_info.c new file mode 100644 index 000000000000..b9c77d20b5c4 --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/adsp_info.c @@ -0,0 +1,121 @@ +/* arch/arm/mach-msm/adsp_info.c + * + * Copyright (c) 2008 QUALCOMM Incorporated. + * Copyright (c) 2008 QUALCOMM USA, INC. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "adsp.h" + +/* Firmware modules */ +#define QDSP_MODULE_KERNEL 0x0106dd4e +#define QDSP_MODULE_AFETASK 0x0106dd6f +#define QDSP_MODULE_AUDPLAY0TASK 0x0106dd70 +#define QDSP_MODULE_AUDPLAY1TASK 0x0106dd71 +#define QDSP_MODULE_AUDPPTASK 0x0106dd72 +#define QDSP_MODULE_VIDEOTASK 0x0106dd73 +#define QDSP_MODULE_VIDEO_AAC_VOC 0x0106dd74 +#define QDSP_MODULE_PCM_DEC 0x0106dd75 +#define QDSP_MODULE_AUDIO_DEC_MP3 0x0106dd76 +#define QDSP_MODULE_AUDIO_DEC_AAC 0x0106dd77 +#define QDSP_MODULE_AUDIO_DEC_WMA 0x0106dd78 +#define QDSP_MODULE_HOSTPCM 0x0106dd79 +#define QDSP_MODULE_DTMF 0x0106dd7a +#define QDSP_MODULE_AUDRECTASK 0x0106dd7b +#define QDSP_MODULE_AUDPREPROCTASK 0x0106dd7c +#define QDSP_MODULE_SBC_ENC 0x0106dd7d +#define QDSP_MODULE_VOC_UMTS 0x0106dd9a +#define QDSP_MODULE_VOC_CDMA 0x0106dd98 +#define QDSP_MODULE_VOC_PCM 0x0106dd7f +#define QDSP_MODULE_VOCENCTASK 0x0106dd80 +#define QDSP_MODULE_VOCDECTASK 0x0106dd81 +#define QDSP_MODULE_VOICEPROCTASK 0x0106dd82 +#define QDSP_MODULE_VIDEOENCTASK 0x0106dd83 +#define QDSP_MODULE_VFETASK 0x0106dd84 +#define QDSP_MODULE_WAV_ENC 0x0106dd85 +#define QDSP_MODULE_AACLC_ENC 0x0106dd86 +#define QDSP_MODULE_VIDEO_AMR 0x0106dd87 +#define QDSP_MODULE_VOC_AMR 0x0106dd88 +#define QDSP_MODULE_VOC_EVRC 0x0106dd89 +#define QDSP_MODULE_VOC_13K 0x0106dd8a +#define QDSP_MODULE_VOC_FGV 0x0106dd8b +#define QDSP_MODULE_DIAGTASK 0x0106dd8c +#define QDSP_MODULE_JPEGTASK 0x0106dd8d +#define QDSP_MODULE_LPMTASK 0x0106dd8e +#define QDSP_MODULE_QCAMTASK 0x0106dd8f +#define QDSP_MODULE_MODMATHTASK 0x0106dd90 +#define QDSP_MODULE_AUDPLAY2TASK 0x0106dd91 +#define QDSP_MODULE_AUDPLAY3TASK 0x0106dd92 +#define QDSP_MODULE_AUDPLAY4TASK 0x0106dd93 +#define QDSP_MODULE_GRAPHICSTASK 0x0106dd94 +#define QDSP_MODULE_MIDI 0x0106dd95 +#define QDSP_MODULE_GAUDIO 0x0106dd96 +#define QDSP_MODULE_VDEC_LP_MODE 0x0106dd97 +#define QDSP_MODULE_MAX 0x7fffffff + + /* DO NOT USE: Force this enum to be a 32bit type to improve speed */ +#define QDSP_MODULE_32BIT_DUMMY 0x10000 + +static uint32_t *qdsp_task_to_module[IMG_MAX]; +static uint32_t *qdsp_queue_offset_table[IMG_MAX]; + +#define QDSP_MODULE(n, clkname, clkrate, verify_cmd_func, patch_event_func) \ + { .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n, \ + .clk_name = clkname, .clk_rate = clkrate, \ + .verify_cmd = verify_cmd_func, .patch_event = patch_event_func } + +static struct adsp_module_info module_info[] = { + QDSP_MODULE(AUDPLAY0TASK, NULL, 0, NULL, NULL), + QDSP_MODULE(AUDPPTASK, NULL, 0, NULL, NULL), + QDSP_MODULE(AUDRECTASK, NULL, 0, NULL, NULL), + QDSP_MODULE(AUDPREPROCTASK, NULL, 0, NULL, NULL), + QDSP_MODULE(VFETASK, "vfe_clk", 0, adsp_vfe_verify_cmd, + adsp_vfe_patch_event), + QDSP_MODULE(QCAMTASK, NULL, 0, NULL, NULL), + QDSP_MODULE(LPMTASK, NULL, 0, adsp_lpm_verify_cmd, NULL), + QDSP_MODULE(JPEGTASK, "vdc_clk", 96000000, adsp_jpeg_verify_cmd, + adsp_jpeg_patch_event), + QDSP_MODULE(VIDEOTASK, "vdc_clk", 96000000, + adsp_video_verify_cmd, NULL), + QDSP_MODULE(VDEC_LP_MODE, NULL, 0, NULL, NULL), + QDSP_MODULE(VIDEOENCTASK, "vdc_clk", 96000000, + adsp_videoenc_verify_cmd, NULL), +}; + +int adsp_init_info(struct adsp_info *info) +{ + uint32_t img_num; + + info->send_irq = 0x00c00200; + info->read_ctrl = 0x00400038; + info->write_ctrl = 0x00400034; + + info->max_msg16_size = 193; + info->max_msg32_size = 8; + for (img_num = 0; img_num < IMG_MAX; img_num++) + qdsp_queue_offset_table[img_num] = + &info->init_info_ptr->queue_offsets[img_num][0]; + + for (img_num = 0; img_num < IMG_MAX; img_num++) + qdsp_task_to_module[img_num] = + &info->init_info_ptr->task_to_module_tbl[img_num][0]; + info->max_task_id = 30; + info->max_module_id = QDSP_MODULE_MAX - 1; + info->max_queue_id = QDSP_MAX_NUM_QUEUES; + info->max_image_id = 2; + info->queue_offset = qdsp_queue_offset_table; + info->task_to_module = qdsp_task_to_module; + + info->module_count = ARRAY_SIZE(module_info); + info->module = module_info; + return 0; +} diff --git a/trunk/drivers/staging/dream/qdsp5/adsp_jpeg_patch_event.c b/trunk/drivers/staging/dream/qdsp5/adsp_jpeg_patch_event.c new file mode 100644 index 000000000000..4f493edb6c94 --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/adsp_jpeg_patch_event.c @@ -0,0 +1,31 @@ +/* arch/arm/mach-msm/qdsp5/adsp_jpeg_patch_event.c + * + * Verification code for aDSP JPEG events. + * + * Copyright (c) 2008 QUALCOMM Incorporated + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "adsp.h" + +int adsp_jpeg_patch_event(struct msm_adsp_module *module, + struct adsp_event *event) +{ + if (event->msg_id == JPEG_MSG_ENC_OP_PRODUCED) { + jpeg_msg_enc_op_produced *op = (jpeg_msg_enc_op_produced *)event->data.msg16; + return adsp_pmem_paddr_fixup(module, (void **)&op->op_buf_addr); + } + + return 0; +} diff --git a/trunk/drivers/staging/dream/qdsp5/adsp_jpeg_verify_cmd.c b/trunk/drivers/staging/dream/qdsp5/adsp_jpeg_verify_cmd.c new file mode 100644 index 000000000000..b33eba25569c --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/adsp_jpeg_verify_cmd.c @@ -0,0 +1,182 @@ +/* arch/arm/mach-msm/qdsp5/adsp_jpeg_verify_cmd.c + * + * Verification code for aDSP JPEG packets from userspace. + * + * Copyright (c) 2008 QUALCOMM Incorporated + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "adsp.h" + +static uint32_t dec_fmt; + +static inline void get_sizes(jpeg_cmd_enc_cfg *cmd, uint32_t *luma_size, + uint32_t *chroma_size) +{ + uint32_t fmt, luma_width, luma_height; + + fmt = cmd->process_cfg & JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_M; + luma_width = (cmd->ip_size_cfg & JPEG_CMD_IP_SIZE_CFG_LUMA_WIDTH_M) + >> 16; + luma_height = cmd->frag_cfg & JPEG_CMD_FRAG_SIZE_LUMA_HEIGHT_M; + *luma_size = luma_width * luma_height; + if (fmt == JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V2) + *chroma_size = *luma_size/2; + else + *chroma_size = *luma_size; +} + +static inline int verify_jpeg_cmd_enc_cfg(struct msm_adsp_module *module, + void *cmd_data, size_t cmd_size) +{ + jpeg_cmd_enc_cfg *cmd = (jpeg_cmd_enc_cfg *)cmd_data; + uint32_t luma_size, chroma_size; + int i, num_frags; + + if (cmd_size != sizeof(jpeg_cmd_enc_cfg)) { + printk(KERN_ERR "adsp: module %s: JPEG ENC CFG invalid cmd_size %d\n", + module->name, cmd_size); + return -1; + } + + get_sizes(cmd, &luma_size, &chroma_size); + num_frags = (cmd->process_cfg >> 10) & 0xf; + num_frags = ((num_frags == 1) ? num_frags : num_frags * 2); + for (i = 0; i < num_frags; i += 2) { + if (adsp_pmem_fixup(module, (void **)(&cmd->frag_cfg_part[i]), luma_size) || + adsp_pmem_fixup(module, (void **)(&cmd->frag_cfg_part[i+1]), chroma_size)) + return -1; + } + + if (adsp_pmem_fixup(module, (void **)&cmd->op_buf_0_cfg_part1, + cmd->op_buf_0_cfg_part2) || + adsp_pmem_fixup(module, (void **)&cmd->op_buf_1_cfg_part1, + cmd->op_buf_1_cfg_part2)) + return -1; + return 0; +} + +static inline int verify_jpeg_cmd_dec_cfg(struct msm_adsp_module *module, + void *cmd_data, size_t cmd_size) +{ + jpeg_cmd_dec_cfg *cmd = (jpeg_cmd_dec_cfg *)cmd_data; + uint32_t div; + + if (cmd_size != sizeof(jpeg_cmd_dec_cfg)) { + printk(KERN_ERR "adsp: module %s: JPEG DEC CFG invalid cmd_size %d\n", + module->name, cmd_size); + return -1; + } + + if (adsp_pmem_fixup(module, (void **)&cmd->ip_stream_buf_cfg_part1, + cmd->ip_stream_buf_cfg_part2) || + adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_0_cfg_part1, + cmd->op_stream_buf_0_cfg_part2) || + adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_1_cfg_part1, + cmd->op_stream_buf_1_cfg_part2)) + return -1; + dec_fmt = cmd->op_data_format & + JPEG_CMD_DEC_OP_DATA_FORMAT_M; + div = (dec_fmt == JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2) ? 2 : 1; + if (adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_0_cfg_part3, + cmd->op_stream_buf_0_cfg_part2 / div) || + adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_1_cfg_part3, + cmd->op_stream_buf_1_cfg_part2 / div)) + return -1; + return 0; +} + +static int verify_jpeg_cfg_cmd(struct msm_adsp_module *module, + void *cmd_data, size_t cmd_size) +{ + uint32_t cmd_id = ((uint32_t *)cmd_data)[0]; + switch(cmd_id) { + case JPEG_CMD_ENC_CFG: + return verify_jpeg_cmd_enc_cfg(module, cmd_data, cmd_size); + case JPEG_CMD_DEC_CFG: + return verify_jpeg_cmd_dec_cfg(module, cmd_data, cmd_size); + default: + if (cmd_id > 1) { + printk(KERN_ERR "adsp: module %s: invalid JPEG CFG cmd_id %d\n", module->name, cmd_id); + return -1; + } + } + return 0; +} + +static int verify_jpeg_action_cmd(struct msm_adsp_module *module, + void *cmd_data, size_t cmd_size) +{ + uint32_t cmd_id = ((uint32_t *)cmd_data)[0]; + switch (cmd_id) { + case JPEG_CMD_ENC_OP_CONSUMED: + { + jpeg_cmd_enc_op_consumed *cmd = + (jpeg_cmd_enc_op_consumed *)cmd_data; + + if (cmd_size != sizeof(jpeg_cmd_enc_op_consumed)) { + printk(KERN_ERR "adsp: module %s: JPEG_CMD_ENC_OP_CONSUMED invalid size %d\n", + module->name, cmd_size); + return -1; + } + + if (adsp_pmem_fixup(module, (void **)&cmd->op_buf_addr, + cmd->op_buf_size)) + return -1; + } + break; + case JPEG_CMD_DEC_OP_CONSUMED: + { + uint32_t div; + jpeg_cmd_dec_op_consumed *cmd = + (jpeg_cmd_dec_op_consumed *)cmd_data; + + if (cmd_size != sizeof(jpeg_cmd_enc_op_consumed)) { + printk(KERN_ERR "adsp: module %s: JPEG_CMD_DEC_OP_CONSUMED invalid size %d\n", + module->name, cmd_size); + return -1; + } + + div = (dec_fmt == JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2) ? 2 : 1; + if (adsp_pmem_fixup(module, (void **)&cmd->luma_op_buf_addr, + cmd->luma_op_buf_size) || + adsp_pmem_fixup(module, (void **)&cmd->chroma_op_buf_addr, + cmd->luma_op_buf_size / div)) + return -1; + } + break; + default: + if (cmd_id > 7) { + printk(KERN_ERR "adsp: module %s: invalid cmd_id %d\n", + module->name, cmd_id); + return -1; + } + } + return 0; +} + +int adsp_jpeg_verify_cmd(struct msm_adsp_module *module, + unsigned int queue_id, void *cmd_data, + size_t cmd_size) +{ + switch(queue_id) { + case QDSP_uPJpegCfgCmdQueue: + return verify_jpeg_cfg_cmd(module, cmd_data, cmd_size); + case QDSP_uPJpegActionCmdQueue: + return verify_jpeg_action_cmd(module, cmd_data, cmd_size); + default: + return -1; + } +} + diff --git a/trunk/drivers/staging/dream/qdsp5/adsp_lpm_verify_cmd.c b/trunk/drivers/staging/dream/qdsp5/adsp_lpm_verify_cmd.c new file mode 100644 index 000000000000..1e23ef392700 --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/adsp_lpm_verify_cmd.c @@ -0,0 +1,65 @@ +/* arch/arm/mach-msm/qdsp5/adsp_lpm_verify_cmd.c + * + * Verificion code for aDSP LPM packets from userspace. + * + * Copyright (c) 2008 QUALCOMM Incorporated + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "adsp.h" + +int adsp_lpm_verify_cmd(struct msm_adsp_module *module, + unsigned int queue_id, void *cmd_data, + size_t cmd_size) +{ + uint32_t cmd_id, col_height, input_row_incr, output_row_incr, + input_size, output_size; + uint32_t size_mask = 0x0fff; + lpm_cmd_start *cmd; + + if (queue_id != QDSP_lpmCommandQueue) { + printk(KERN_ERR "adsp: module %s: wrong queue id %d\n", + module->name, queue_id); + return -1; + } + + cmd = (lpm_cmd_start *)cmd_data; + cmd_id = cmd->cmd_id; + + if (cmd_id == LPM_CMD_START) { + if (cmd_size != sizeof(lpm_cmd_start)) { + printk(KERN_ERR "adsp: module %s: wrong size %d, expect %d\n", + module->name, cmd_size, sizeof(lpm_cmd_start)); + return -1; + } + col_height = cmd->ip_data_cfg_part1 & size_mask; + input_row_incr = cmd->ip_data_cfg_part2 & size_mask; + output_row_incr = cmd->op_data_cfg_part1 & size_mask; + input_size = col_height * input_row_incr; + output_size = col_height * output_row_incr; + if ((cmd->ip_data_cfg_part4 && adsp_pmem_fixup(module, + (void **)(&cmd->ip_data_cfg_part4), + input_size)) || + (cmd->op_data_cfg_part3 && adsp_pmem_fixup(module, + (void **)(&cmd->op_data_cfg_part3), + output_size))) + return -1; + } else if (cmd_id > 1) { + printk(KERN_ERR "adsp: module %s: invalid cmd_id %d\n", + module->name, cmd_id); + return -1; + } + return 0; +} + diff --git a/trunk/drivers/staging/dream/qdsp5/adsp_vfe_patch_event.c b/trunk/drivers/staging/dream/qdsp5/adsp_vfe_patch_event.c new file mode 100644 index 000000000000..a56392b3521c --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/adsp_vfe_patch_event.c @@ -0,0 +1,54 @@ +/* arch/arm/mach-msm/qdsp5/adsp_vfe_patch_event.c + * + * Verification code for aDSP VFE packets from userspace. + * + * Copyright (c) 2008 QUALCOMM Incorporated + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "adsp.h" + +static int patch_op_event(struct msm_adsp_module *module, + struct adsp_event *event) +{ + vfe_msg_op1 *op = (vfe_msg_op1 *)event->data.msg16; + if (adsp_pmem_paddr_fixup(module, (void **)&op->op1_buf_y_addr) || + adsp_pmem_paddr_fixup(module, (void **)&op->op1_buf_cbcr_addr)) + return -1; + return 0; +} + +static int patch_af_wb_event(struct msm_adsp_module *module, + struct adsp_event *event) +{ + vfe_msg_stats_wb_exp *af = (vfe_msg_stats_wb_exp *)event->data.msg16; + return adsp_pmem_paddr_fixup(module, (void **)&af->wb_exp_stats_op_buf); +} + +int adsp_vfe_patch_event(struct msm_adsp_module *module, + struct adsp_event *event) +{ + switch(event->msg_id) { + case VFE_MSG_OP1: + case VFE_MSG_OP2: + return patch_op_event(module, event); + case VFE_MSG_STATS_AF: + case VFE_MSG_STATS_WB_EXP: + return patch_af_wb_event(module, event); + default: + break; + } + + return 0; +} diff --git a/trunk/drivers/staging/dream/qdsp5/adsp_vfe_verify_cmd.c b/trunk/drivers/staging/dream/qdsp5/adsp_vfe_verify_cmd.c new file mode 100644 index 000000000000..927d50a730ff --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/adsp_vfe_verify_cmd.c @@ -0,0 +1,239 @@ +/* arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c + * + * Verification code for aDSP VFE packets from userspace. + * + * Copyright (c) 2008 QUALCOMM Incorporated + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "adsp.h" + +static uint32_t size1_y, size2_y, size1_cbcr, size2_cbcr; +static uint32_t af_size = 4228; +static uint32_t awb_size = 8196; + +static inline int verify_cmd_op_ack(struct msm_adsp_module *module, + void *cmd_data, size_t cmd_size) +{ + vfe_cmd_op1_ack *cmd = (vfe_cmd_op1_ack *)cmd_data; + void **addr_y = (void **)&cmd->op1_buf_y_addr; + void **addr_cbcr = (void **)(&cmd->op1_buf_cbcr_addr); + + if (cmd_size != sizeof(vfe_cmd_op1_ack)) + return -1; + if ((*addr_y && adsp_pmem_fixup(module, addr_y, size1_y)) || + (*addr_cbcr && adsp_pmem_fixup(module, addr_cbcr, size1_cbcr))) + return -1; + return 0; +} + +static inline int verify_cmd_stats_autofocus_cfg(struct msm_adsp_module *module, + void *cmd_data, size_t cmd_size) +{ + int i; + vfe_cmd_stats_autofocus_cfg *cmd = + (vfe_cmd_stats_autofocus_cfg *)cmd_data; + + if (cmd_size != sizeof(vfe_cmd_stats_autofocus_cfg)) + return -1; + + for (i = 0; i < 3; i++) { + void **addr = (void **)(&cmd->af_stats_op_buf[i]); + if (*addr && adsp_pmem_fixup(module, addr, af_size)) + return -1; + } + return 0; +} + +static inline int verify_cmd_stats_wb_exp_cfg(struct msm_adsp_module *module, + void *cmd_data, size_t cmd_size) +{ + vfe_cmd_stats_wb_exp_cfg *cmd = + (vfe_cmd_stats_wb_exp_cfg *)cmd_data; + int i; + + if (cmd_size != sizeof(vfe_cmd_stats_wb_exp_cfg)) + return -1; + + for (i = 0; i < 3; i++) { + void **addr = (void **)(&cmd->wb_exp_stats_op_buf[i]); + if (*addr && adsp_pmem_fixup(module, addr, awb_size)) + return -1; + } + return 0; +} + +static inline int verify_cmd_stats_af_ack(struct msm_adsp_module *module, + void *cmd_data, size_t cmd_size) +{ + vfe_cmd_stats_af_ack *cmd = (vfe_cmd_stats_af_ack *)cmd_data; + void **addr = (void **)&cmd->af_stats_op_buf; + + if (cmd_size != sizeof(vfe_cmd_stats_af_ack)) + return -1; + + if (*addr && adsp_pmem_fixup(module, addr, af_size)) + return -1; + return 0; +} + +static inline int verify_cmd_stats_wb_exp_ack(struct msm_adsp_module *module, + void *cmd_data, size_t cmd_size) +{ + vfe_cmd_stats_wb_exp_ack *cmd = + (vfe_cmd_stats_wb_exp_ack *)cmd_data; + void **addr = (void **)&cmd->wb_exp_stats_op_buf; + + if (cmd_size != sizeof(vfe_cmd_stats_wb_exp_ack)) + return -1; + + if (*addr && adsp_pmem_fixup(module, addr, awb_size)) + return -1; + return 0; +} + +static int verify_vfe_command(struct msm_adsp_module *module, + void *cmd_data, size_t cmd_size) +{ + uint32_t cmd_id = ((uint32_t *)cmd_data)[0]; + switch (cmd_id) { + case VFE_CMD_OP1_ACK: + return verify_cmd_op_ack(module, cmd_data, cmd_size); + case VFE_CMD_OP2_ACK: + return verify_cmd_op_ack(module, cmd_data, cmd_size); + case VFE_CMD_STATS_AUTOFOCUS_CFG: + return verify_cmd_stats_autofocus_cfg(module, cmd_data, + cmd_size); + case VFE_CMD_STATS_WB_EXP_CFG: + return verify_cmd_stats_wb_exp_cfg(module, cmd_data, cmd_size); + case VFE_CMD_STATS_AF_ACK: + return verify_cmd_stats_af_ack(module, cmd_data, cmd_size); + case VFE_CMD_STATS_WB_EXP_ACK: + return verify_cmd_stats_wb_exp_ack(module, cmd_data, cmd_size); + default: + if (cmd_id > 29) { + printk(KERN_ERR "adsp: module %s: invalid VFE command id %d\n", module->name, cmd_id); + return -1; + } + } + return 0; +} + +static int verify_vfe_command_scale(struct msm_adsp_module *module, + void *cmd_data, size_t cmd_size) +{ + uint32_t cmd_id = ((uint32_t *)cmd_data)[0]; + // FIXME: check the size + if (cmd_id > 1) { + printk(KERN_ERR "adsp: module %s: invalid VFE SCALE command id %d\n", module->name, cmd_id); + return -1; + } + return 0; +} + + +static uint32_t get_size(uint32_t hw) +{ + uint32_t height, width; + uint32_t height_mask = 0x3ffc; + uint32_t width_mask = 0x3ffc000; + + height = (hw & height_mask) >> 2; + width = (hw & width_mask) >> 14 ; + return height * width; +} + +static int verify_vfe_command_table(struct msm_adsp_module *module, + void *cmd_data, size_t cmd_size) +{ + uint32_t cmd_id = ((uint32_t *)cmd_data)[0]; + int i; + + switch (cmd_id) { + case VFE_CMD_AXI_IP_CFG: + { + vfe_cmd_axi_ip_cfg *cmd = (vfe_cmd_axi_ip_cfg *)cmd_data; + uint32_t size; + if (cmd_size != sizeof(vfe_cmd_axi_ip_cfg)) { + printk(KERN_ERR "adsp: module %s: invalid VFE TABLE (VFE_CMD_AXI_IP_CFG) command size %d\n", + module->name, cmd_size); + return -1; + } + size = get_size(cmd->ip_cfg_part2); + + for (i = 0; i < 8; i++) { + void **addr = (void **) + &cmd->ip_buf_addr[i]; + if (*addr && adsp_pmem_fixup(module, addr, size)) + return -1; + } + } + case VFE_CMD_AXI_OP_CFG: + { + vfe_cmd_axi_op_cfg *cmd = (vfe_cmd_axi_op_cfg *)cmd_data; + void **addr1_y, **addr2_y, **addr1_cbcr, **addr2_cbcr; + + if (cmd_size != sizeof(vfe_cmd_axi_op_cfg)) { + printk(KERN_ERR "adsp: module %s: invalid VFE TABLE (VFE_CMD_AXI_OP_CFG) command size %d\n", + module->name, cmd_size); + return -1; + } + size1_y = get_size(cmd->op1_y_cfg_part2); + size1_cbcr = get_size(cmd->op1_cbcr_cfg_part2); + size2_y = get_size(cmd->op2_y_cfg_part2); + size2_cbcr = get_size(cmd->op2_cbcr_cfg_part2); + for (i = 0; i < 8; i++) { + addr1_y = (void **)(&cmd->op1_buf1_addr[2*i]); + addr1_cbcr = (void **)(&cmd->op1_buf1_addr[2*i+1]); + addr2_y = (void **)(&cmd->op2_buf1_addr[2*i]); + addr2_cbcr = (void **)(&cmd->op2_buf1_addr[2*i+1]); +/* + printk("module %s: [%d] %p %p %p %p\n", + module->name, i, + *addr1_y, *addr1_cbcr, *addr2_y, *addr2_cbcr); +*/ + if ((*addr1_y && adsp_pmem_fixup(module, addr1_y, size1_y)) || + (*addr1_cbcr && adsp_pmem_fixup(module, addr1_cbcr, size1_cbcr)) || + (*addr2_y && adsp_pmem_fixup(module, addr2_y, size2_y)) || + (*addr2_cbcr && adsp_pmem_fixup(module, addr2_cbcr, size2_cbcr))) + return -1; + } + } + default: + if (cmd_id > 4) { + printk(KERN_ERR "adsp: module %s: invalid VFE TABLE command id %d\n", + module->name, cmd_id); + return -1; + } + } + return 0; +} + +int adsp_vfe_verify_cmd(struct msm_adsp_module *module, + unsigned int queue_id, void *cmd_data, + size_t cmd_size) +{ + switch (queue_id) { + case QDSP_vfeCommandQueue: + return verify_vfe_command(module, cmd_data, cmd_size); + case QDSP_vfeCommandScaleQueue: + return verify_vfe_command_scale(module, cmd_data, cmd_size); + case QDSP_vfeCommandTableQueue: + return verify_vfe_command_table(module, cmd_data, cmd_size); + default: + printk(KERN_ERR "adsp: module %s: unknown queue id %d\n", + module->name, queue_id); + return -1; + } +} diff --git a/trunk/drivers/staging/dream/qdsp5/adsp_video_verify_cmd.c b/trunk/drivers/staging/dream/qdsp5/adsp_video_verify_cmd.c new file mode 100644 index 000000000000..53aff77cfd92 --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/adsp_video_verify_cmd.c @@ -0,0 +1,163 @@ +/* arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c + * + * Verificion code for aDSP VDEC packets from userspace. + * + * Copyright (c) 2008 QUALCOMM Incorporated + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include + +#define ADSP_DEBUG_MSGS 0 +#if ADSP_DEBUG_MSGS +#define DLOG(fmt,args...) \ + do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \ + ##args); } \ + while (0) +#else +#define DLOG(x...) do {} while (0) +#endif + + +#include +#include "adsp.h" + +static inline void *high_low_short_to_ptr(unsigned short high, + unsigned short low) +{ + return (void *)((((unsigned long)high) << 16) | ((unsigned long)low)); +} + +static inline void ptr_to_high_low_short(void *ptr, unsigned short *high, + unsigned short *low) +{ + *high = (unsigned short)((((unsigned long)ptr) >> 16) & 0xffff); + *low = (unsigned short)((unsigned long)ptr & 0xffff); +} + +static int pmem_fixup_high_low(unsigned short *high, + unsigned short *low, + unsigned short size_high, + unsigned short size_low, + struct msm_adsp_module *module, + unsigned long *addr, unsigned long *size) +{ + void *phys_addr; + unsigned long phys_size; + unsigned long kvaddr; + + phys_addr = high_low_short_to_ptr(*high, *low); + phys_size = (unsigned long)high_low_short_to_ptr(size_high, size_low); + DLOG("virt %x %x\n", phys_addr, phys_size); + if (adsp_pmem_fixup_kvaddr(module, &phys_addr, &kvaddr, phys_size)) { + DLOG("ah%x al%x sh%x sl%x addr %x size %x\n", + *high, *low, size_high, size_low, phys_addr, phys_size); + return -1; + } + ptr_to_high_low_short(phys_addr, high, low); + DLOG("phys %x %x\n", phys_addr, phys_size); + if (addr) + *addr = kvaddr; + if (size) + *size = phys_size; + return 0; +} + +static int verify_vdec_pkt_cmd(struct msm_adsp_module *module, + void *cmd_data, size_t cmd_size) +{ + unsigned short cmd_id = ((unsigned short *)cmd_data)[0]; + viddec_cmd_subframe_pkt *pkt; + unsigned long subframe_pkt_addr; + unsigned long subframe_pkt_size; + viddec_cmd_frame_header_packet *frame_header_pkt; + int i, num_addr, skip; + unsigned short *frame_buffer_high, *frame_buffer_low; + unsigned long frame_buffer_size; + unsigned short frame_buffer_size_high, frame_buffer_size_low; + + DLOG("cmd_size %d cmd_id %d cmd_data %x\n", cmd_size, cmd_id, cmd_data); + if (cmd_id != VIDDEC_CMD_SUBFRAME_PKT) { + printk(KERN_INFO "adsp_video: unknown video packet %u\n", + cmd_id); + return 0; + } + if (cmd_size < sizeof(viddec_cmd_subframe_pkt)) + return -1; + + pkt = (viddec_cmd_subframe_pkt *)cmd_data; + + if (pmem_fixup_high_low(&(pkt->subframe_packet_high), + &(pkt->subframe_packet_low), + pkt->subframe_packet_size_high, + pkt->subframe_packet_size_low, + module, + &subframe_pkt_addr, + &subframe_pkt_size)) + return -1; + + /* deref those ptrs and check if they are a frame header packet */ + frame_header_pkt = (viddec_cmd_frame_header_packet *)subframe_pkt_addr; + + switch (frame_header_pkt->packet_id) { + case 0xB201: /* h.264 */ + num_addr = skip = 8; + break; + case 0x4D01: /* mpeg-4 and h.263 */ + num_addr = 3; + skip = 0; + break; + default: + return 0; + } + + frame_buffer_high = &frame_header_pkt->frame_buffer_0_high; + frame_buffer_low = &frame_header_pkt->frame_buffer_0_low; + frame_buffer_size = (frame_header_pkt->x_dimension * + frame_header_pkt->y_dimension * 3) / 2; + ptr_to_high_low_short((void *)frame_buffer_size, + &frame_buffer_size_high, + &frame_buffer_size_low); + for (i = 0; i < num_addr; i++) { + if (pmem_fixup_high_low(frame_buffer_high, frame_buffer_low, + frame_buffer_size_high, + frame_buffer_size_low, + module, + NULL, NULL)) + return -1; + frame_buffer_high += 2; + frame_buffer_low += 2; + } + /* Patch the output buffer. */ + frame_buffer_high += 2*skip; + frame_buffer_low += 2*skip; + if (pmem_fixup_high_low(frame_buffer_high, frame_buffer_low, + frame_buffer_size_high, + frame_buffer_size_low, module, NULL, NULL)) + return -1; + return 0; +} + +int adsp_video_verify_cmd(struct msm_adsp_module *module, + unsigned int queue_id, void *cmd_data, + size_t cmd_size) +{ + switch (queue_id) { + case QDSP_mpuVDecPktQueue: + DLOG("\n"); + return verify_vdec_pkt_cmd(module, cmd_data, cmd_size); + default: + printk(KERN_INFO "unknown video queue %u\n", queue_id); + return 0; + } +} + diff --git a/trunk/drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c b/trunk/drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c new file mode 100644 index 000000000000..ee3744950523 --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c @@ -0,0 +1,235 @@ +/* arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c + * + * Verificion code for aDSP VENC packets from userspace. + * + * Copyright (c) 2008 QUALCOMM Incorporated + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include + +#define ADSP_DEBUG_MSGS 0 +#if ADSP_DEBUG_MSGS +#define DLOG(fmt,args...) \ + do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \ + ##args); } \ + while (0) +#else +#define DLOG(x...) do {} while (0) +#endif + +#include +#include "adsp.h" + + +static unsigned short x_dimension, y_dimension; + +static inline void *high_low_short_to_ptr(unsigned short high, + unsigned short low) +{ + return (void *)((((unsigned long)high) << 16) | ((unsigned long)low)); +} + +static inline void ptr_to_high_low_short(void *ptr, unsigned short *high, + unsigned short *low) +{ + *high = (unsigned short)((((unsigned long)ptr) >> 16) & 0xffff); + *low = (unsigned short)((unsigned long)ptr & 0xffff); +} + +static int pmem_fixup_high_low(unsigned short *high, + unsigned short *low, + unsigned short size_high, + unsigned short size_low, + struct msm_adsp_module *module, + unsigned long *addr, unsigned long *size) +{ + void *phys_addr; + unsigned long phys_size; + unsigned long kvaddr; + + phys_addr = high_low_short_to_ptr(*high, *low); + phys_size = (unsigned long)high_low_short_to_ptr(size_high, size_low); + DLOG("virt %x %x\n", phys_addr, phys_size); + if (adsp_pmem_fixup_kvaddr(module, &phys_addr, &kvaddr, phys_size)) { + DLOG("ah%x al%x sh%x sl%x addr %x size %x\n", + *high, *low, size_high, size_low, phys_addr, phys_size); + return -1; + } + ptr_to_high_low_short(phys_addr, high, low); + DLOG("phys %x %x\n", phys_addr, phys_size); + if (addr) + *addr = kvaddr; + if (size) + *size = phys_size; + return 0; +} + +static int verify_venc_cmd(struct msm_adsp_module *module, + void *cmd_data, size_t cmd_size) +{ + unsigned short cmd_id = ((unsigned short *)cmd_data)[0]; + unsigned long frame_buf_size, luma_buf_size, chroma_buf_size; + unsigned short frame_buf_size_high, frame_buf_size_low; + unsigned short luma_buf_size_high, luma_buf_size_low; + unsigned short chroma_buf_size_high, chroma_buf_size_low; + videnc_cmd_cfg *config_cmd; + videnc_cmd_frame_start *frame_cmd; + videnc_cmd_dis *dis_cmd; + + DLOG("cmd_size %d cmd_id %d cmd_data %x\n", cmd_size, cmd_id, cmd_data); + switch (cmd_id) { + case VIDENC_CMD_ACTIVE: + if (cmd_size < sizeof(videnc_cmd_active)) + return -1; + break; + case VIDENC_CMD_IDLE: + if (cmd_size < sizeof(videnc_cmd_idle)) + return -1; + x_dimension = y_dimension = 0; + break; + case VIDENC_CMD_STATUS_QUERY: + if (cmd_size < sizeof(videnc_cmd_status_query)) + return -1; + break; + case VIDENC_CMD_RC_CFG: + if (cmd_size < sizeof(videnc_cmd_rc_cfg)) + return -1; + break; + case VIDENC_CMD_INTRA_REFRESH: + if (cmd_size < sizeof(videnc_cmd_intra_refresh)) + return -1; + break; + case VIDENC_CMD_DIGITAL_ZOOM: + if (cmd_size < sizeof(videnc_cmd_digital_zoom)) + return -1; + break; + case VIDENC_CMD_DIS_CFG: + if (cmd_size < sizeof(videnc_cmd_dis_cfg)) + return -1; + break; + case VIDENC_CMD_CFG: + if (cmd_size < sizeof(videnc_cmd_cfg)) + return -1; + config_cmd = (videnc_cmd_cfg *)cmd_data; + x_dimension = ((config_cmd->venc_frame_dim) & 0xFF00)>>8; + x_dimension = x_dimension*16; + y_dimension = (config_cmd->venc_frame_dim) & 0xFF; + y_dimension = y_dimension * 16; + break; + case VIDENC_CMD_FRAME_START: + if (cmd_size < sizeof(videnc_cmd_frame_start)) + return -1; + frame_cmd = (videnc_cmd_frame_start *)cmd_data; + luma_buf_size = x_dimension * y_dimension; + chroma_buf_size = luma_buf_size>>1; + frame_buf_size = luma_buf_size + chroma_buf_size; + ptr_to_high_low_short((void *)luma_buf_size, + &luma_buf_size_high, + &luma_buf_size_low); + ptr_to_high_low_short((void *)chroma_buf_size, + &chroma_buf_size_high, + &chroma_buf_size_low); + ptr_to_high_low_short((void *)frame_buf_size, + &frame_buf_size_high, + &frame_buf_size_low); + /* Address of raw Y data. */ + if (pmem_fixup_high_low(&frame_cmd->input_luma_addr_high, + &frame_cmd->input_luma_addr_low, + luma_buf_size_high, + luma_buf_size_low, + module, + NULL, NULL)) + return -1; + /* Address of raw CbCr data */ + if (pmem_fixup_high_low(&frame_cmd->input_chroma_addr_high, + &frame_cmd->input_chroma_addr_low, + chroma_buf_size_high, + chroma_buf_size_low, + module, + NULL, NULL)) + return -1; + /* Reference VOP */ + if (pmem_fixup_high_low(&frame_cmd->ref_vop_buf_ptr_high, + &frame_cmd->ref_vop_buf_ptr_low, + frame_buf_size_high, + frame_buf_size_low, + module, + NULL, NULL)) + return -1; + /* Encoded Packet Address */ + if (pmem_fixup_high_low(&frame_cmd->enc_pkt_buf_ptr_high, + &frame_cmd->enc_pkt_buf_ptr_low, + frame_cmd->enc_pkt_buf_size_high, + frame_cmd->enc_pkt_buf_size_low, + module, + NULL, NULL)) + return -1; + /* Unfiltered VOP Buffer Address */ + if (pmem_fixup_high_low( + &frame_cmd->unfilt_recon_vop_buf_ptr_high, + &frame_cmd->unfilt_recon_vop_buf_ptr_low, + frame_buf_size_high, + frame_buf_size_low, + module, + NULL, NULL)) + return -1; + /* Filtered VOP Buffer Address */ + if (pmem_fixup_high_low(&frame_cmd->filt_recon_vop_buf_ptr_high, + &frame_cmd->filt_recon_vop_buf_ptr_low, + frame_buf_size_high, + frame_buf_size_low, + module, + NULL, NULL)) + return -1; + break; + case VIDENC_CMD_DIS: + if (cmd_size < sizeof(videnc_cmd_dis)) + return -1; + dis_cmd = (videnc_cmd_dis *)cmd_data; + luma_buf_size = x_dimension * y_dimension; + ptr_to_high_low_short((void *)luma_buf_size, + &luma_buf_size_high, + &luma_buf_size_low); + /* Prev VFE Luma Output Address */ + if (pmem_fixup_high_low(&dis_cmd->vfe_out_prev_luma_addr_high, + &dis_cmd->vfe_out_prev_luma_addr_low, + luma_buf_size_high, + luma_buf_size_low, + module, + NULL, NULL)) + return -1; + break; + default: + printk(KERN_INFO "adsp_video:unknown encoder video command %u\n", + cmd_id); + return 0; + } + + return 0; +} + + +int adsp_videoenc_verify_cmd(struct msm_adsp_module *module, + unsigned int queue_id, void *cmd_data, + size_t cmd_size) +{ + switch (queue_id) { + case QDSP_mpuVEncCmdQueue: + DLOG("\n"); + return verify_venc_cmd(module, cmd_data, cmd_size); + default: + printk(KERN_INFO "unknown video queue %u\n", queue_id); + return 0; + } +} + diff --git a/trunk/drivers/staging/dream/qdsp5/audio_aac.c b/trunk/drivers/staging/dream/qdsp5/audio_aac.c new file mode 100644 index 000000000000..45f4c78ab6e7 --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/audio_aac.c @@ -0,0 +1,1054 @@ +/* arch/arm/mach-msm/qdsp5/audio_aac.c + * + * aac audio decoder device + * + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * Copyright (c) 2008-2009 QUALCOMM USA, INC. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include "audmgr.h" + +#include +#include +#include +#include +#include +#include + +/* for queue ids - should be relative to module number*/ +#include "adsp.h" + +#ifdef DEBUG +#define dprintk(format, arg...) \ +printk(KERN_DEBUG format, ## arg) +#else +#define dprintk(format, arg...) do {} while (0) +#endif + +#define BUFSZ 32768 +#define DMASZ (BUFSZ * 2) + +#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF +#define AUDDEC_DEC_AAC 5 + +#define PCM_BUFSZ_MIN 9600 /* Hold one stereo AAC frame */ +#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most + but support 2 buffers currently */ +#define ROUTING_MODE_FTRT 1 +#define ROUTING_MODE_RT 2 +/* Decoder status received from AUDPPTASK */ +#define AUDPP_DEC_STATUS_SLEEP 0 +#define AUDPP_DEC_STATUS_INIT 1 +#define AUDPP_DEC_STATUS_CFG 2 +#define AUDPP_DEC_STATUS_PLAY 3 + +struct buffer { + void *data; + unsigned size; + unsigned used; /* Input usage actual DSP produced PCM size */ + unsigned addr; +}; + +struct audio { + struct buffer out[2]; + + spinlock_t dsp_lock; + + uint8_t out_head; + uint8_t out_tail; + uint8_t out_needed; /* number of buffers the dsp is waiting for */ + + atomic_t out_bytes; + + struct mutex lock; + struct mutex write_lock; + wait_queue_head_t write_wait; + + /* Host PCM section */ + struct buffer in[PCM_BUF_MAX_COUNT]; + struct mutex read_lock; + wait_queue_head_t read_wait; /* Wait queue for read */ + char *read_data; /* pointer to reader buffer */ + dma_addr_t read_phys; /* physical address of reader buffer */ + uint8_t read_next; /* index to input buffers to be read next */ + uint8_t fill_next; /* index to buffer that DSP should be filling */ + uint8_t pcm_buf_count; /* number of pcm buffer allocated */ + /* ---- End of Host PCM section */ + + struct msm_adsp_module *audplay; + + /* configuration to use on next enable */ + uint32_t out_sample_rate; + uint32_t out_channel_mode; + struct msm_audio_aac_config aac_config; + struct audmgr audmgr; + + /* data allocated for various buffers */ + char *data; + dma_addr_t phys; + + int rflush; /* Read flush */ + int wflush; /* Write flush */ + int opened; + int enabled; + int running; + int stopped; /* set when stopped, cleared on flush */ + int pcm_feedback; + int buf_refresh; + + int reserved; /* A byte is being reserved */ + char rsv_byte; /* Handle odd length user data */ + + unsigned volume; + + uint16_t dec_id; + uint32_t read_ptr_offset; +}; + +static int auddec_dsp_config(struct audio *audio, int enable); +static void audpp_cmd_cfg_adec_params(struct audio *audio); +static void audpp_cmd_cfg_routing_mode(struct audio *audio); +static void audplay_send_data(struct audio *audio, unsigned needed); +static void audplay_config_hostpcm(struct audio *audio); +static void audplay_buffer_refresh(struct audio *audio); +static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); + +/* must be called with audio->lock held */ +static int audio_enable(struct audio *audio) +{ + struct audmgr_config cfg; + int rc; + + dprintk("audio_enable()\n"); + + if (audio->enabled) + return 0; + + audio->out_tail = 0; + audio->out_needed = 0; + + cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; + cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; + cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK; + cfg.codec = RPC_AUD_DEF_CODEC_AAC; + cfg.snd_method = RPC_SND_METHOD_MIDI; + + rc = audmgr_enable(&audio->audmgr, &cfg); + if (rc < 0) + return rc; + + if (msm_adsp_enable(audio->audplay)) { + pr_err("audio: msm_adsp_enable(audplay) failed\n"); + audmgr_disable(&audio->audmgr); + return -ENODEV; + } + + if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) { + pr_err("audio: audpp_enable() failed\n"); + msm_adsp_disable(audio->audplay); + audmgr_disable(&audio->audmgr); + return -ENODEV; + } + audio->enabled = 1; + return 0; +} + +/* must be called with audio->lock held */ +static int audio_disable(struct audio *audio) +{ + dprintk("audio_disable()\n"); + if (audio->enabled) { + audio->enabled = 0; + auddec_dsp_config(audio, 0); + wake_up(&audio->write_wait); + wake_up(&audio->read_wait); + msm_adsp_disable(audio->audplay); + audpp_disable(audio->dec_id, audio); + audmgr_disable(&audio->audmgr); + audio->out_needed = 0; + } + return 0; +} + +/* ------------------- dsp --------------------- */ +static void audio_update_pcm_buf_entry(struct audio *audio, uint32_t *payload) +{ + uint8_t index; + unsigned long flags; + + if (audio->rflush) + return; + + spin_lock_irqsave(&audio->dsp_lock, flags); + for (index = 0; index < payload[1]; index++) { + if (audio->in[audio->fill_next].addr == + payload[2 + index * 2]) { + dprintk("audio_update_pcm_buf_entry: in[%d] ready\n", + audio->fill_next); + audio->in[audio->fill_next].used = + payload[3 + index * 2]; + if ((++audio->fill_next) == audio->pcm_buf_count) + audio->fill_next = 0; + + } else { + pr_err + ("audio_update_pcm_buf_entry: expected=%x ret=%x\n" + , audio->in[audio->fill_next].addr, + payload[1 + index * 2]); + break; + } + } + if (audio->in[audio->fill_next].used == 0) { + audplay_buffer_refresh(audio); + } else { + dprintk("audio_update_pcm_buf_entry: read cannot keep up\n"); + audio->buf_refresh = 1; + } + wake_up(&audio->read_wait); + spin_unlock_irqrestore(&audio->dsp_lock, flags); + +} + +static void audplay_dsp_event(void *data, unsigned id, size_t len, + void (*getevent) (void *ptr, size_t len)) +{ + struct audio *audio = data; + uint32_t msg[28]; + getevent(msg, sizeof(msg)); + + dprintk("audplay_dsp_event: msg_id=%x\n", id); + + switch (id) { + case AUDPLAY_MSG_DEC_NEEDS_DATA: + audplay_send_data(audio, 1); + break; + + case AUDPLAY_MSG_BUFFER_UPDATE: + audio_update_pcm_buf_entry(audio, msg); + break; + + default: + pr_err("unexpected message from decoder \n"); + } +} + +static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) +{ + struct audio *audio = private; + + switch (id) { + case AUDPP_MSG_STATUS_MSG:{ + unsigned status = msg[1]; + + switch (status) { + case AUDPP_DEC_STATUS_SLEEP: + dprintk("decoder status: sleep \n"); + break; + + case AUDPP_DEC_STATUS_INIT: + dprintk("decoder status: init \n"); + audpp_cmd_cfg_routing_mode(audio); + break; + + case AUDPP_DEC_STATUS_CFG: + dprintk("decoder status: cfg \n"); + break; + case AUDPP_DEC_STATUS_PLAY: + dprintk("decoder status: play \n"); + if (audio->pcm_feedback) { + audplay_config_hostpcm(audio); + audplay_buffer_refresh(audio); + } + break; + default: + pr_err("unknown decoder status \n"); + } + break; + } + case AUDPP_MSG_CFG_MSG: + if (msg[0] == AUDPP_MSG_ENA_ENA) { + dprintk("audio_dsp_event: CFG_MSG ENABLE\n"); + auddec_dsp_config(audio, 1); + audio->out_needed = 0; + audio->running = 1; + audpp_set_volume_and_pan(audio->dec_id, audio->volume, + 0); + audpp_avsync(audio->dec_id, 22050); + } else if (msg[0] == AUDPP_MSG_ENA_DIS) { + dprintk("audio_dsp_event: CFG_MSG DISABLE\n"); + audpp_avsync(audio->dec_id, 0); + audio->running = 0; + } else { + pr_err("audio_dsp_event: CFG_MSG %d?\n", msg[0]); + } + break; + case AUDPP_MSG_ROUTING_ACK: + dprintk("audio_dsp_event: ROUTING_ACK mode=%d\n", msg[1]); + audpp_cmd_cfg_adec_params(audio); + break; + + case AUDPP_MSG_FLUSH_ACK: + dprintk("%s: FLUSH_ACK\n", __func__); + audio->wflush = 0; + audio->rflush = 0; + if (audio->pcm_feedback) + audplay_buffer_refresh(audio); + break; + + default: + pr_err("audio_dsp_event: UNKNOWN (%d)\n", id); + } + +} + +struct msm_adsp_ops audplay_adsp_ops_aac = { + .event = audplay_dsp_event, +}; + +#define audplay_send_queue0(audio, cmd, len) \ + msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \ + cmd, len) + +static int auddec_dsp_config(struct audio *audio, int enable) +{ + audpp_cmd_cfg_dec_type cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE; + if (enable) + cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | + AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AAC; + else + cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V; + + return audpp_send_queue1(&cmd, sizeof(cmd)); +} + +static void audpp_cmd_cfg_adec_params(struct audio *audio) +{ + audpp_cmd_cfg_adec_params_aac cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; + cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_AAC_LEN; + cmd.common.dec_id = audio->dec_id; + cmd.common.input_sampling_frequency = audio->out_sample_rate; + cmd.format = audio->aac_config.format; + cmd.audio_object = audio->aac_config.audio_object; + cmd.ep_config = audio->aac_config.ep_config; + cmd.aac_section_data_resilience_flag = + audio->aac_config.aac_section_data_resilience_flag; + cmd.aac_scalefactor_data_resilience_flag = + audio->aac_config.aac_scalefactor_data_resilience_flag; + cmd.aac_spectral_data_resilience_flag = + audio->aac_config.aac_spectral_data_resilience_flag; + cmd.sbr_on_flag = audio->aac_config.sbr_on_flag; + cmd.sbr_ps_on_flag = audio->aac_config.sbr_ps_on_flag; + cmd.channel_configuration = audio->aac_config.channel_configuration; + + audpp_send_queue2(&cmd, sizeof(cmd)); +} + +static void audpp_cmd_cfg_routing_mode(struct audio *audio) +{ + struct audpp_cmd_routing_mode cmd; + dprintk("audpp_cmd_cfg_routing_mode()\n"); + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; + cmd.object_number = audio->dec_id; + if (audio->pcm_feedback) + cmd.routing_mode = ROUTING_MODE_FTRT; + else + cmd.routing_mode = ROUTING_MODE_RT; + + audpp_send_queue1(&cmd, sizeof(cmd)); +} + +static int audplay_dsp_send_data_avail(struct audio *audio, + unsigned idx, unsigned len) +{ + audplay_cmd_bitstream_data_avail cmd; + + cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL; + cmd.decoder_id = audio->dec_id; + cmd.buf_ptr = audio->out[idx].addr; + cmd.buf_size = len / 2; + cmd.partition_number = 0; + return audplay_send_queue0(audio, &cmd, sizeof(cmd)); +} + +static void audplay_buffer_refresh(struct audio *audio) +{ + struct audplay_cmd_buffer_refresh refresh_cmd; + + refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; + refresh_cmd.num_buffers = 1; + refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; + refresh_cmd.buf0_length = audio->in[audio->fill_next].size - + (audio->in[audio->fill_next].size % 1024); /* AAC frame size */ + refresh_cmd.buf_read_count = 0; + dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n", + refresh_cmd.buf0_address, refresh_cmd.buf0_length); + (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); +} + +static void audplay_config_hostpcm(struct audio *audio) +{ + struct audplay_cmd_hpcm_buf_cfg cfg_cmd; + + dprintk("audplay_config_hostpcm()\n"); + cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; + cfg_cmd.max_buffers = audio->pcm_buf_count; + cfg_cmd.byte_swap = 0; + cfg_cmd.hostpcm_config = (0x8000) | (0x4000); + cfg_cmd.feedback_frequency = 1; + cfg_cmd.partition_number = 0; + (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); + +} + +static void audplay_send_data(struct audio *audio, unsigned needed) +{ + struct buffer *frame; + unsigned long flags; + + spin_lock_irqsave(&audio->dsp_lock, flags); + if (!audio->running) + goto done; + + if (needed && !audio->wflush) { + /* We were called from the callback because the DSP + * requested more data. Note that the DSP does want + * more data, and if a buffer was in-flight, mark it + * as available (since the DSP must now be done with + * it). + */ + audio->out_needed = 1; + frame = audio->out + audio->out_tail; + if (frame->used == 0xffffffff) { + dprintk("frame %d free\n", audio->out_tail); + frame->used = 0; + audio->out_tail ^= 1; + wake_up(&audio->write_wait); + } + } + + if (audio->out_needed) { + /* If the DSP currently wants data and we have a + * buffer available, we will send it and reset + * the needed flag. We'll mark the buffer as in-flight + * so that it won't be recycled until the next buffer + * is requested + */ + + frame = audio->out + audio->out_tail; + if (frame->used) { + BUG_ON(frame->used == 0xffffffff); +/* printk("frame %d busy\n", audio->out_tail); */ + audplay_dsp_send_data_avail(audio, audio->out_tail, + frame->used); + frame->used = 0xffffffff; + audio->out_needed = 0; + } + } + done: + spin_unlock_irqrestore(&audio->dsp_lock, flags); +} + +/* ------------------- device --------------------- */ + +static void audio_flush(struct audio *audio) +{ + audio->out[0].used = 0; + audio->out[1].used = 0; + audio->out_head = 0; + audio->out_tail = 0; + audio->reserved = 0; + audio->out_needed = 0; + atomic_set(&audio->out_bytes, 0); +} + +static void audio_flush_pcm_buf(struct audio *audio) +{ + uint8_t index; + + for (index = 0; index < PCM_BUF_MAX_COUNT; index++) + audio->in[index].used = 0; + audio->buf_refresh = 0; + audio->read_next = 0; + audio->fill_next = 0; +} + +static int audaac_validate_usr_config(struct msm_audio_aac_config *config) +{ + int ret_val = -1; + + if (config->format != AUDIO_AAC_FORMAT_ADTS && + config->format != AUDIO_AAC_FORMAT_RAW && + config->format != AUDIO_AAC_FORMAT_PSUEDO_RAW && + config->format != AUDIO_AAC_FORMAT_LOAS) + goto done; + + if (config->audio_object != AUDIO_AAC_OBJECT_LC && + config->audio_object != AUDIO_AAC_OBJECT_LTP && + config->audio_object != AUDIO_AAC_OBJECT_ERLC) + goto done; + + if (config->audio_object == AUDIO_AAC_OBJECT_ERLC) { + if (config->ep_config > 3) + goto done; + if (config->aac_scalefactor_data_resilience_flag != + AUDIO_AAC_SCA_DATA_RES_OFF && + config->aac_scalefactor_data_resilience_flag != + AUDIO_AAC_SCA_DATA_RES_ON) + goto done; + if (config->aac_section_data_resilience_flag != + AUDIO_AAC_SEC_DATA_RES_OFF && + config->aac_section_data_resilience_flag != + AUDIO_AAC_SEC_DATA_RES_ON) + goto done; + if (config->aac_spectral_data_resilience_flag != + AUDIO_AAC_SPEC_DATA_RES_OFF && + config->aac_spectral_data_resilience_flag != + AUDIO_AAC_SPEC_DATA_RES_ON) + goto done; + } else { + config->aac_section_data_resilience_flag = + AUDIO_AAC_SEC_DATA_RES_OFF; + config->aac_scalefactor_data_resilience_flag = + AUDIO_AAC_SCA_DATA_RES_OFF; + config->aac_spectral_data_resilience_flag = + AUDIO_AAC_SPEC_DATA_RES_OFF; + } + + if (config->sbr_on_flag != AUDIO_AAC_SBR_ON_FLAG_OFF && + config->sbr_on_flag != AUDIO_AAC_SBR_ON_FLAG_ON) + goto done; + + if (config->sbr_ps_on_flag != AUDIO_AAC_SBR_PS_ON_FLAG_OFF && + config->sbr_ps_on_flag != AUDIO_AAC_SBR_PS_ON_FLAG_ON) + goto done; + + if (config->dual_mono_mode > AUDIO_AAC_DUAL_MONO_PL_SR) + goto done; + + if (config->channel_configuration > 2) + goto done; + + ret_val = 0; + done: + return ret_val; +} + +static void audio_ioport_reset(struct audio *audio) +{ + /* Make sure read/write thread are free from + * sleep and knowing that system is not able + * to process io request at the moment + */ + wake_up(&audio->write_wait); + mutex_lock(&audio->write_lock); + audio_flush(audio); + mutex_unlock(&audio->write_lock); + wake_up(&audio->read_wait); + mutex_lock(&audio->read_lock); + audio_flush_pcm_buf(audio); + mutex_unlock(&audio->read_lock); +} + +static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct audio *audio = file->private_data; + int rc = 0; + + dprintk("audio_ioctl() cmd = %d\n", cmd); + + if (cmd == AUDIO_GET_STATS) { + struct msm_audio_stats stats; + stats.byte_count = audpp_avsync_byte_count(audio->dec_id); + stats.sample_count = audpp_avsync_sample_count(audio->dec_id); + if (copy_to_user((void *)arg, &stats, sizeof(stats))) + return -EFAULT; + return 0; + } + if (cmd == AUDIO_SET_VOLUME) { + unsigned long flags; + spin_lock_irqsave(&audio->dsp_lock, flags); + audio->volume = arg; + if (audio->running) + audpp_set_volume_and_pan(audio->dec_id, arg, 0); + spin_unlock_irqrestore(&audio->dsp_lock, flags); + return 0; + } + mutex_lock(&audio->lock); + switch (cmd) { + case AUDIO_START: + rc = audio_enable(audio); + break; + case AUDIO_STOP: + rc = audio_disable(audio); + audio->stopped = 1; + audio_ioport_reset(audio); + audio->stopped = 0; + break; + case AUDIO_FLUSH: + dprintk("%s: AUDIO_FLUSH\n", __func__); + audio->rflush = 1; + audio->wflush = 1; + audio_ioport_reset(audio); + if (audio->running) + audpp_flush(audio->dec_id); + else { + audio->rflush = 0; + audio->wflush = 0; + } + break; + + case AUDIO_SET_CONFIG:{ + struct msm_audio_config config; + + if (copy_from_user + (&config, (void *)arg, sizeof(config))) { + rc = -EFAULT; + break; + } + + if (config.channel_count == 1) { + config.channel_count = + AUDPP_CMD_PCM_INTF_MONO_V; + } else if (config.channel_count == 2) { + config.channel_count = + AUDPP_CMD_PCM_INTF_STEREO_V; + } else { + rc = -EINVAL; + break; + } + + audio->out_sample_rate = config.sample_rate; + audio->out_channel_mode = config.channel_count; + rc = 0; + break; + } + case AUDIO_GET_CONFIG:{ + struct msm_audio_config config; + config.buffer_size = BUFSZ; + config.buffer_count = 2; + config.sample_rate = audio->out_sample_rate; + if (audio->out_channel_mode == + AUDPP_CMD_PCM_INTF_MONO_V) { + config.channel_count = 1; + } else { + config.channel_count = 2; + } + config.unused[0] = 0; + config.unused[1] = 0; + config.unused[2] = 0; + config.unused[3] = 0; + if (copy_to_user((void *)arg, &config, + sizeof(config))) + rc = -EFAULT; + else + rc = 0; + + break; + } + case AUDIO_GET_AAC_CONFIG:{ + if (copy_to_user((void *)arg, &audio->aac_config, + sizeof(audio->aac_config))) + rc = -EFAULT; + else + rc = 0; + break; + } + case AUDIO_SET_AAC_CONFIG:{ + struct msm_audio_aac_config usr_config; + + if (copy_from_user + (&usr_config, (void *)arg, + sizeof(usr_config))) { + rc = -EFAULT; + break; + } + + if (audaac_validate_usr_config(&usr_config) == 0) { + audio->aac_config = usr_config; + rc = 0; + } else + rc = -EINVAL; + + break; + } + case AUDIO_GET_PCM_CONFIG:{ + struct msm_audio_pcm_config config; + config.pcm_feedback = 0; + config.buffer_count = PCM_BUF_MAX_COUNT; + config.buffer_size = PCM_BUFSZ_MIN; + if (copy_to_user((void *)arg, &config, + sizeof(config))) + rc = -EFAULT; + else + rc = 0; + break; + } + case AUDIO_SET_PCM_CONFIG:{ + struct msm_audio_pcm_config config; + if (copy_from_user + (&config, (void *)arg, sizeof(config))) { + rc = -EFAULT; + break; + } + if ((config.buffer_count > PCM_BUF_MAX_COUNT) || + (config.buffer_count == 1)) + config.buffer_count = PCM_BUF_MAX_COUNT; + + if (config.buffer_size < PCM_BUFSZ_MIN) + config.buffer_size = PCM_BUFSZ_MIN; + + /* Check if pcm feedback is required */ + if ((config.pcm_feedback) && (!audio->read_data)) { + dprintk("ioctl: allocate PCM buffer %d\n", + config.buffer_count * + config.buffer_size); + audio->read_data = + dma_alloc_coherent(NULL, + config.buffer_size * + config.buffer_count, + &audio->read_phys, + GFP_KERNEL); + if (!audio->read_data) { + pr_err("audio_aac: buf alloc fail\n"); + rc = -1; + } else { + uint8_t index; + uint32_t offset = 0; + audio->pcm_feedback = 1; + audio->buf_refresh = 0; + audio->pcm_buf_count = + config.buffer_count; + audio->read_next = 0; + audio->fill_next = 0; + + for (index = 0; + index < config.buffer_count; + index++) { + audio->in[index].data = + audio->read_data + offset; + audio->in[index].addr = + audio->read_phys + offset; + audio->in[index].size = + config.buffer_size; + audio->in[index].used = 0; + offset += config.buffer_size; + } + rc = 0; + } + } else { + rc = 0; + } + break; + } + case AUDIO_PAUSE: + dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg); + rc = audpp_pause(audio->dec_id, (int) arg); + break; + default: + rc = -EINVAL; + } + mutex_unlock(&audio->lock); + return rc; +} + +static ssize_t audio_read(struct file *file, char __user *buf, size_t count, + loff_t *pos) +{ + struct audio *audio = file->private_data; + const char __user *start = buf; + int rc = 0; + + if (!audio->pcm_feedback) + return 0; /* PCM feedback is not enabled. Nothing to read */ + + mutex_lock(&audio->read_lock); + dprintk("audio_read() %d \n", count); + while (count > 0) { + rc = wait_event_interruptible(audio->read_wait, + (audio->in[audio->read_next]. + used > 0) || (audio->stopped) + || (audio->rflush)); + + if (rc < 0) + break; + + if (audio->stopped || audio->rflush) { + rc = -EBUSY; + break; + } + + if (count < audio->in[audio->read_next].used) { + /* Read must happen in frame boundary. Since driver + does not know frame size, read count must be greater + or equal to size of PCM samples */ + dprintk("audio_read: no partial frame done reading\n"); + break; + } else { + dprintk("audio_read: read from in[%d]\n", + audio->read_next); + if (copy_to_user + (buf, audio->in[audio->read_next].data, + audio->in[audio->read_next].used)) { + pr_err("audio_read: invalid addr %x \n", + (unsigned int)buf); + rc = -EFAULT; + break; + } + count -= audio->in[audio->read_next].used; + buf += audio->in[audio->read_next].used; + audio->in[audio->read_next].used = 0; + if ((++audio->read_next) == audio->pcm_buf_count) + audio->read_next = 0; + if (audio->in[audio->read_next].used == 0) + break; /* No data ready at this moment + * Exit while loop to prevent + * output thread sleep too long + */ + } + } + + /* don't feed output buffer to HW decoder during flushing + * buffer refresh command will be sent once flush completes + * send buf refresh command here can confuse HW decoder + */ + if (audio->buf_refresh && !audio->rflush) { + audio->buf_refresh = 0; + dprintk("audio_read: kick start pcm feedback again\n"); + audplay_buffer_refresh(audio); + } + + mutex_unlock(&audio->read_lock); + + if (buf > start) + rc = buf - start; + + dprintk("audio_read: read %d bytes\n", rc); + return rc; +} + +static ssize_t audio_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + struct audio *audio = file->private_data; + const char __user *start = buf; + struct buffer *frame; + size_t xfer; + char *cpy_ptr; + int rc = 0; + unsigned dsize; + + mutex_lock(&audio->write_lock); + while (count > 0) { + frame = audio->out + audio->out_head; + cpy_ptr = frame->data; + dsize = 0; + rc = wait_event_interruptible(audio->write_wait, + (frame->used == 0) + || (audio->stopped) + || (audio->wflush)); + if (rc < 0) + break; + if (audio->stopped || audio->wflush) { + rc = -EBUSY; + break; + } + + if (audio->reserved) { + dprintk("%s: append reserved byte %x\n", + __func__, audio->rsv_byte); + *cpy_ptr = audio->rsv_byte; + xfer = (count > (frame->size - 1)) ? + frame->size - 1 : count; + cpy_ptr++; + dsize = 1; + audio->reserved = 0; + } else + xfer = (count > frame->size) ? frame->size : count; + + if (copy_from_user(cpy_ptr, buf, xfer)) { + rc = -EFAULT; + break; + } + + dsize += xfer; + if (dsize & 1) { + audio->rsv_byte = ((char *) frame->data)[dsize - 1]; + dprintk("%s: odd length buf reserve last byte %x\n", + __func__, audio->rsv_byte); + audio->reserved = 1; + dsize--; + } + count -= xfer; + buf += xfer; + + if (dsize > 0) { + audio->out_head ^= 1; + frame->used = dsize; + audplay_send_data(audio, 0); + } + } + mutex_unlock(&audio->write_lock); + if (buf > start) + return buf - start; + return rc; +} + +static int audio_release(struct inode *inode, struct file *file) +{ + struct audio *audio = file->private_data; + + dprintk("audio_release()\n"); + + mutex_lock(&audio->lock); + audio_disable(audio); + audio_flush(audio); + audio_flush_pcm_buf(audio); + msm_adsp_put(audio->audplay); + audio->audplay = NULL; + audio->opened = 0; + audio->reserved = 0; + dma_free_coherent(NULL, DMASZ, audio->data, audio->phys); + audio->data = NULL; + if (audio->read_data != NULL) { + dma_free_coherent(NULL, + audio->in[0].size * audio->pcm_buf_count, + audio->read_data, audio->read_phys); + audio->read_data = NULL; + } + audio->pcm_feedback = 0; + mutex_unlock(&audio->lock); + return 0; +} + +static struct audio the_aac_audio; + +static int audio_open(struct inode *inode, struct file *file) +{ + struct audio *audio = &the_aac_audio; + int rc; + + mutex_lock(&audio->lock); + + if (audio->opened) { + pr_err("audio: busy\n"); + rc = -EBUSY; + goto done; + } + + if (!audio->data) { + audio->data = dma_alloc_coherent(NULL, DMASZ, + &audio->phys, GFP_KERNEL); + if (!audio->data) { + pr_err("audio: could not allocate DMA buffers\n"); + rc = -ENOMEM; + goto done; + } + } + + rc = audmgr_open(&audio->audmgr); + if (rc) + goto done; + + rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay, + &audplay_adsp_ops_aac, audio); + if (rc) { + pr_err("audio: failed to get audplay0 dsp module\n"); + goto done; + } + audio->out_sample_rate = 44100; + audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; + audio->aac_config.format = AUDIO_AAC_FORMAT_ADTS; + audio->aac_config.audio_object = AUDIO_AAC_OBJECT_LC; + audio->aac_config.ep_config = 0; + audio->aac_config.aac_section_data_resilience_flag = + AUDIO_AAC_SEC_DATA_RES_OFF; + audio->aac_config.aac_scalefactor_data_resilience_flag = + AUDIO_AAC_SCA_DATA_RES_OFF; + audio->aac_config.aac_spectral_data_resilience_flag = + AUDIO_AAC_SPEC_DATA_RES_OFF; + audio->aac_config.sbr_on_flag = AUDIO_AAC_SBR_ON_FLAG_ON; + audio->aac_config.sbr_ps_on_flag = AUDIO_AAC_SBR_PS_ON_FLAG_ON; + audio->aac_config.dual_mono_mode = AUDIO_AAC_DUAL_MONO_PL_SR; + audio->aac_config.channel_configuration = 2; + audio->dec_id = 0; + + audio->out[0].data = audio->data + 0; + audio->out[0].addr = audio->phys + 0; + audio->out[0].size = BUFSZ; + + audio->out[1].data = audio->data + BUFSZ; + audio->out[1].addr = audio->phys + BUFSZ; + audio->out[1].size = BUFSZ; + + audio->volume = 0x2000; /* Q13 1.0 */ + + audio_flush(audio); + + file->private_data = audio; + audio->opened = 1; + rc = 0; +done: + mutex_unlock(&audio->lock); + return rc; +} + +static struct file_operations audio_aac_fops = { + .owner = THIS_MODULE, + .open = audio_open, + .release = audio_release, + .read = audio_read, + .write = audio_write, + .unlocked_ioctl = audio_ioctl, + .llseek = noop_llseek, +}; + +struct miscdevice audio_aac_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_aac", + .fops = &audio_aac_fops, +}; + +static int __init audio_init(void) +{ + mutex_init(&the_aac_audio.lock); + mutex_init(&the_aac_audio.write_lock); + mutex_init(&the_aac_audio.read_lock); + spin_lock_init(&the_aac_audio.dsp_lock); + init_waitqueue_head(&the_aac_audio.write_wait); + init_waitqueue_head(&the_aac_audio.read_wait); + the_aac_audio.read_data = NULL; + return misc_register(&audio_aac_misc); +} + +device_initcall(audio_init); diff --git a/trunk/drivers/staging/dream/qdsp5/audio_amrnb.c b/trunk/drivers/staging/dream/qdsp5/audio_amrnb.c new file mode 100644 index 000000000000..402bbc13281a --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/audio_amrnb.c @@ -0,0 +1,875 @@ +/* linux/arch/arm/mach-msm/qdsp5/audio_amrnb.c + * + * amrnb audio decoder device + * + * Copyright (c) 2008 QUALCOMM USA, INC. + * + * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c + * + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * + * All source code in this file is licensed under the following license except + * where indicated. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, you can find it at http://www.fsf.org + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include "audmgr.h" + +#include +#include +#include +#include + +/* for queue ids - should be relative to module number*/ +#include "adsp.h" + +#define DEBUG +#ifdef DEBUG +#define dprintk(format, arg...) \ +printk(KERN_DEBUG format, ## arg) +#else +#define dprintk(format, arg...) do {} while (0) +#endif + +#define BUFSZ 1024 /* Hold minimum 700ms voice data */ +#define DMASZ (BUFSZ * 2) + +#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF +#define AUDDEC_DEC_AMRNB 10 + +#define PCM_BUFSZ_MIN 1600 /* 100ms worth of data */ +#define AMRNB_DECODED_FRSZ 320 /* AMR-NB 20ms 8KHz mono PCM size */ +#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most + but support 2 buffers currently */ +#define ROUTING_MODE_FTRT 1 +#define ROUTING_MODE_RT 2 +/* Decoder status received from AUDPPTASK */ +#define AUDPP_DEC_STATUS_SLEEP 0 +#define AUDPP_DEC_STATUS_INIT 1 +#define AUDPP_DEC_STATUS_CFG 2 +#define AUDPP_DEC_STATUS_PLAY 3 + +struct buffer { + void *data; + unsigned size; + unsigned used; /* Input usage actual DSP produced PCM size */ + unsigned addr; +}; + +struct audio { + struct buffer out[2]; + + spinlock_t dsp_lock; + + uint8_t out_head; + uint8_t out_tail; + uint8_t out_needed; /* number of buffers the dsp is waiting for */ + + atomic_t out_bytes; + + struct mutex lock; + struct mutex write_lock; + wait_queue_head_t write_wait; + + /* Host PCM section */ + struct buffer in[PCM_BUF_MAX_COUNT]; + struct mutex read_lock; + wait_queue_head_t read_wait; /* Wait queue for read */ + char *read_data; /* pointer to reader buffer */ + dma_addr_t read_phys; /* physical address of reader buffer */ + uint8_t read_next; /* index to input buffers to be read next */ + uint8_t fill_next; /* index to buffer that DSP should be filling */ + uint8_t pcm_buf_count; /* number of pcm buffer allocated */ + /* ---- End of Host PCM section */ + + struct msm_adsp_module *audplay; + + struct audmgr audmgr; + + /* data allocated for various buffers */ + char *data; + dma_addr_t phys; + + uint8_t opened:1; + uint8_t enabled:1; + uint8_t running:1; + uint8_t stopped:1; /* set when stopped, cleared on flush */ + uint8_t pcm_feedback:1; + uint8_t buf_refresh:1; + + unsigned volume; + + uint16_t dec_id; + uint32_t read_ptr_offset; +}; + +struct audpp_cmd_cfg_adec_params_amrnb { + audpp_cmd_cfg_adec_params_common common; + unsigned short stereo_cfg; +} __attribute__((packed)) ; + +static int auddec_dsp_config(struct audio *audio, int enable); +static void audpp_cmd_cfg_adec_params(struct audio *audio); +static void audpp_cmd_cfg_routing_mode(struct audio *audio); +static void audamrnb_send_data(struct audio *audio, unsigned needed); +static void audamrnb_config_hostpcm(struct audio *audio); +static void audamrnb_buffer_refresh(struct audio *audio); +static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg); + +/* must be called with audio->lock held */ +static int audamrnb_enable(struct audio *audio) +{ + struct audmgr_config cfg; + int rc; + + dprintk("audamrnb_enable()\n"); + + if (audio->enabled) + return 0; + + audio->out_tail = 0; + audio->out_needed = 0; + + cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; + cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; + cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK; + cfg.codec = RPC_AUD_DEF_CODEC_AMR_NB; + cfg.snd_method = RPC_SND_METHOD_MIDI; + + rc = audmgr_enable(&audio->audmgr, &cfg); + if (rc < 0) + return rc; + + if (msm_adsp_enable(audio->audplay)) { + pr_err("audio: msm_adsp_enable(audplay) failed\n"); + audmgr_disable(&audio->audmgr); + return -ENODEV; + } + + if (audpp_enable(audio->dec_id, audamrnb_dsp_event, audio)) { + pr_err("audio: audpp_enable() failed\n"); + msm_adsp_disable(audio->audplay); + audmgr_disable(&audio->audmgr); + return -ENODEV; + } + audio->enabled = 1; + return 0; +} + +/* must be called with audio->lock held */ +static int audamrnb_disable(struct audio *audio) +{ + dprintk("audamrnb_disable()\n"); + if (audio->enabled) { + audio->enabled = 0; + auddec_dsp_config(audio, 0); + wake_up(&audio->write_wait); + wake_up(&audio->read_wait); + msm_adsp_disable(audio->audplay); + audpp_disable(audio->dec_id, audio); + audmgr_disable(&audio->audmgr); + audio->out_needed = 0; + } + return 0; +} + +/* ------------------- dsp --------------------- */ +static void audamrnb_update_pcm_buf_entry(struct audio *audio, + uint32_t *payload) +{ + uint8_t index; + unsigned long flags; + + spin_lock_irqsave(&audio->dsp_lock, flags); + for (index = 0; index < payload[1]; index++) { + if (audio->in[audio->fill_next].addr == + payload[2 + index * 2]) { + dprintk("audamrnb_update_pcm_buf_entry: in[%d] ready\n", + audio->fill_next); + audio->in[audio->fill_next].used = + payload[3 + index * 2]; + if ((++audio->fill_next) == audio->pcm_buf_count) + audio->fill_next = 0; + + } else { + pr_err + ("audamrnb_update_pcm_buf_entry: expected=%x ret=%x\n" + , audio->in[audio->fill_next].addr, + payload[1 + index * 2]); + break; + } + } + if (audio->in[audio->fill_next].used == 0) { + audamrnb_buffer_refresh(audio); + } else { + dprintk("audamrnb_update_pcm_buf_entry: read cannot keep up\n"); + audio->buf_refresh = 1; + } + + spin_unlock_irqrestore(&audio->dsp_lock, flags); + wake_up(&audio->read_wait); +} + +static void audplay_dsp_event(void *data, unsigned id, size_t len, + void (*getevent) (void *ptr, size_t len)) +{ + struct audio *audio = data; + uint32_t msg[28]; + getevent(msg, sizeof(msg)); + + dprintk("audplay_dsp_event: msg_id=%x\n", id); + + switch (id) { + case AUDPLAY_MSG_DEC_NEEDS_DATA: + audamrnb_send_data(audio, 1); + break; + + case AUDPLAY_MSG_BUFFER_UPDATE: + audamrnb_update_pcm_buf_entry(audio, msg); + break; + + default: + pr_err("unexpected message from decoder \n"); + } +} + +static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg) +{ + struct audio *audio = private; + + switch (id) { + case AUDPP_MSG_STATUS_MSG:{ + unsigned status = msg[1]; + + switch (status) { + case AUDPP_DEC_STATUS_SLEEP: + dprintk("decoder status: sleep \n"); + break; + + case AUDPP_DEC_STATUS_INIT: + dprintk("decoder status: init \n"); + audpp_cmd_cfg_routing_mode(audio); + break; + + case AUDPP_DEC_STATUS_CFG: + dprintk("decoder status: cfg \n"); + break; + case AUDPP_DEC_STATUS_PLAY: + dprintk("decoder status: play \n"); + if (audio->pcm_feedback) { + audamrnb_config_hostpcm(audio); + audamrnb_buffer_refresh(audio); + } + break; + default: + pr_err("unknown decoder status \n"); + break; + } + break; + } + case AUDPP_MSG_CFG_MSG: + if (msg[0] == AUDPP_MSG_ENA_ENA) { + dprintk("audamrnb_dsp_event: CFG_MSG ENABLE\n"); + auddec_dsp_config(audio, 1); + audio->out_needed = 0; + audio->running = 1; + audpp_set_volume_and_pan(audio->dec_id, audio->volume, + 0); + audpp_avsync(audio->dec_id, 22050); + } else if (msg[0] == AUDPP_MSG_ENA_DIS) { + dprintk("audamrnb_dsp_event: CFG_MSG DISABLE\n"); + audpp_avsync(audio->dec_id, 0); + audio->running = 0; + } else { + pr_err("audamrnb_dsp_event: CFG_MSG %d?\n", msg[0]); + } + break; + case AUDPP_MSG_ROUTING_ACK: + dprintk("audamrnb_dsp_event: ROUTING_ACK mode=%d\n", msg[1]); + audpp_cmd_cfg_adec_params(audio); + break; + + default: + pr_err("audamrnb_dsp_event: UNKNOWN (%d)\n", id); + } + +} + +struct msm_adsp_ops audplay_adsp_ops_amrnb = { + .event = audplay_dsp_event, +}; + +#define audplay_send_queue0(audio, cmd, len) \ + msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \ + cmd, len) + +static int auddec_dsp_config(struct audio *audio, int enable) +{ + audpp_cmd_cfg_dec_type cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE; + if (enable) + cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | + AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AMRNB; + else + cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V; + + return audpp_send_queue1(&cmd, sizeof(cmd)); +} + +static void audpp_cmd_cfg_adec_params(struct audio *audio) +{ + struct audpp_cmd_cfg_adec_params_amrnb cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; + cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN; + cmd.common.dec_id = audio->dec_id; + cmd.common.input_sampling_frequency = 8000; + cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V; + + audpp_send_queue2(&cmd, sizeof(cmd)); +} + +static void audpp_cmd_cfg_routing_mode(struct audio *audio) +{ + struct audpp_cmd_routing_mode cmd; + dprintk("audpp_cmd_cfg_routing_mode()\n"); + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; + cmd.object_number = audio->dec_id; + if (audio->pcm_feedback) + cmd.routing_mode = ROUTING_MODE_FTRT; + else + cmd.routing_mode = ROUTING_MODE_RT; + + audpp_send_queue1(&cmd, sizeof(cmd)); +} + +static int audplay_dsp_send_data_avail(struct audio *audio, + unsigned idx, unsigned len) +{ + audplay_cmd_bitstream_data_avail cmd; + + cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL; + cmd.decoder_id = audio->dec_id; + cmd.buf_ptr = audio->out[idx].addr; + cmd.buf_size = len / 2; + cmd.partition_number = 0; + return audplay_send_queue0(audio, &cmd, sizeof(cmd)); +} + +static void audamrnb_buffer_refresh(struct audio *audio) +{ + struct audplay_cmd_buffer_refresh refresh_cmd; + + refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; + refresh_cmd.num_buffers = 1; + refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; + refresh_cmd.buf0_length = audio->in[audio->fill_next].size - + (audio->in[audio->fill_next].size % AMRNB_DECODED_FRSZ); + refresh_cmd.buf_read_count = 0; + dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n", + refresh_cmd.buf0_address, refresh_cmd.buf0_length); + (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); +} + +static void audamrnb_config_hostpcm(struct audio *audio) +{ + struct audplay_cmd_hpcm_buf_cfg cfg_cmd; + + dprintk("audamrnb_config_hostpcm()\n"); + cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; + cfg_cmd.max_buffers = audio->pcm_buf_count; + cfg_cmd.byte_swap = 0; + cfg_cmd.hostpcm_config = (0x8000) | (0x4000); + cfg_cmd.feedback_frequency = 1; + cfg_cmd.partition_number = 0; + (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); + +} + +static void audamrnb_send_data(struct audio *audio, unsigned needed) +{ + struct buffer *frame; + unsigned long flags; + + spin_lock_irqsave(&audio->dsp_lock, flags); + if (!audio->running) + goto done; + + if (needed) { + /* We were called from the callback because the DSP + * requested more data. Note that the DSP does want + * more data, and if a buffer was in-flight, mark it + * as available (since the DSP must now be done with + * it). + */ + audio->out_needed = 1; + frame = audio->out + audio->out_tail; + if (frame->used == 0xffffffff) { + frame->used = 0; + audio->out_tail ^= 1; + wake_up(&audio->write_wait); + } + } + + if (audio->out_needed) { + /* If the DSP currently wants data and we have a + * buffer available, we will send it and reset + * the needed flag. We'll mark the buffer as in-flight + * so that it won't be recycled until the next buffer + * is requested + */ + + frame = audio->out + audio->out_tail; + if (frame->used) { + BUG_ON(frame->used == 0xffffffff); +/* printk("frame %d busy\n", audio->out_tail); */ + audplay_dsp_send_data_avail(audio, audio->out_tail, + frame->used); + frame->used = 0xffffffff; + audio->out_needed = 0; + } + } + done: + spin_unlock_irqrestore(&audio->dsp_lock, flags); +} + +/* ------------------- device --------------------- */ + +static void audamrnb_flush(struct audio *audio) +{ + audio->out[0].used = 0; + audio->out[1].used = 0; + audio->out_head = 0; + audio->out_tail = 0; + audio->stopped = 0; + atomic_set(&audio->out_bytes, 0); +} + +static void audamrnb_flush_pcm_buf(struct audio *audio) +{ + uint8_t index; + + for (index = 0; index < PCM_BUF_MAX_COUNT; index++) + audio->in[index].used = 0; + + audio->read_next = 0; + audio->fill_next = 0; +} + +static long audamrnb_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct audio *audio = file->private_data; + int rc = 0; + + dprintk("audamrnb_ioctl() cmd = %d\n", cmd); + + if (cmd == AUDIO_GET_STATS) { + struct msm_audio_stats stats; + stats.byte_count = audpp_avsync_byte_count(audio->dec_id); + stats.sample_count = audpp_avsync_sample_count(audio->dec_id); + if (copy_to_user((void *)arg, &stats, sizeof(stats))) + return -EFAULT; + return 0; + } + if (cmd == AUDIO_SET_VOLUME) { + unsigned long flags; + spin_lock_irqsave(&audio->dsp_lock, flags); + audio->volume = arg; + if (audio->running) + audpp_set_volume_and_pan(audio->dec_id, arg, 0); + spin_unlock_irqrestore(&audio->dsp_lock, flags); + return 0; + } + mutex_lock(&audio->lock); + switch (cmd) { + case AUDIO_START: + rc = audamrnb_enable(audio); + break; + case AUDIO_STOP: + rc = audamrnb_disable(audio); + audio->stopped = 1; + break; + case AUDIO_FLUSH: + if (audio->stopped) { + /* Make sure we're stopped and we wake any threads + * that might be blocked holding the write_lock. + * While audio->stopped write threads will always + * exit immediately. + */ + wake_up(&audio->write_wait); + mutex_lock(&audio->write_lock); + audamrnb_flush(audio); + mutex_unlock(&audio->write_lock); + wake_up(&audio->read_wait); + mutex_lock(&audio->read_lock); + audamrnb_flush_pcm_buf(audio); + mutex_unlock(&audio->read_lock); + break; + } + + case AUDIO_SET_CONFIG:{ + dprintk("AUDIO_SET_CONFIG not applicable \n"); + break; + } + case AUDIO_GET_CONFIG:{ + struct msm_audio_config config; + config.buffer_size = BUFSZ; + config.buffer_count = 2; + config.sample_rate = 8000; + config.channel_count = 1; + config.unused[0] = 0; + config.unused[1] = 0; + config.unused[2] = 0; + config.unused[3] = 0; + if (copy_to_user((void *)arg, &config, + sizeof(config))) + rc = -EFAULT; + else + rc = 0; + + break; + } + case AUDIO_GET_PCM_CONFIG:{ + struct msm_audio_pcm_config config; + config.pcm_feedback = 0; + config.buffer_count = PCM_BUF_MAX_COUNT; + config.buffer_size = PCM_BUFSZ_MIN; + if (copy_to_user((void *)arg, &config, + sizeof(config))) + rc = -EFAULT; + else + rc = 0; + break; + } + case AUDIO_SET_PCM_CONFIG:{ + struct msm_audio_pcm_config config; + if (copy_from_user + (&config, (void *)arg, sizeof(config))) { + rc = -EFAULT; + break; + } + if ((config.buffer_count > PCM_BUF_MAX_COUNT) || + (config.buffer_count == 1)) + config.buffer_count = PCM_BUF_MAX_COUNT; + + if (config.buffer_size < PCM_BUFSZ_MIN) + config.buffer_size = PCM_BUFSZ_MIN; + + /* Check if pcm feedback is required */ + if ((config.pcm_feedback) && (!audio->read_data)) { + dprintk("audamrnb_ioctl: allocate PCM buf %d\n", + config.buffer_count * + config.buffer_size); + audio->read_data = + dma_alloc_coherent(NULL, + config.buffer_size * + config.buffer_count, + &audio->read_phys, + GFP_KERNEL); + if (!audio->read_data) { + pr_err("audamrnb_ioctl: no mem for pcm buf\n"); + rc = -1; + } else { + uint8_t index; + uint32_t offset = 0; + audio->pcm_feedback = 1; + audio->buf_refresh = 0; + audio->pcm_buf_count = + config.buffer_count; + audio->read_next = 0; + audio->fill_next = 0; + + for (index = 0; + index < config.buffer_count; index++) { + audio->in[index].data = + audio->read_data + offset; + audio->in[index].addr = + audio->read_phys + offset; + audio->in[index].size = + config.buffer_size; + audio->in[index].used = 0; + offset += config.buffer_size; + } + rc = 0; + } + } else { + rc = 0; + } + break; + } + default: + rc = -EINVAL; + } + mutex_unlock(&audio->lock); + return rc; +} + +static ssize_t audamrnb_read(struct file *file, char __user *buf, size_t count, + loff_t *pos) +{ + struct audio *audio = file->private_data; + const char __user *start = buf; + int rc = 0; + + if (!audio->pcm_feedback) + return 0; /* PCM feedback is not enabled. Nothing to read */ + + mutex_lock(&audio->read_lock); + dprintk("audamrnb_read() %d \n", count); + while (count > 0) { + rc = wait_event_interruptible(audio->read_wait, + (audio->in[audio->read_next]. + used > 0) || (audio->stopped)); + + if (rc < 0) + break; + + if (audio->stopped) { + rc = -EBUSY; + break; + } + + if (count < audio->in[audio->read_next].used) { + /* Read must happen in frame boundary. Since driver does + * not know frame size, read count must be greater or + * equal to size of PCM samples + */ + dprintk("audamrnb_read:read stop - partial frame\n"); + break; + } else { + dprintk("audamrnb_read: read from in[%d]\n", + audio->read_next); + if (copy_to_user + (buf, audio->in[audio->read_next].data, + audio->in[audio->read_next].used)) { + pr_err("audamrnb_read: invalid addr %x \n", + (unsigned int)buf); + rc = -EFAULT; + break; + } + count -= audio->in[audio->read_next].used; + buf += audio->in[audio->read_next].used; + audio->in[audio->read_next].used = 0; + if ((++audio->read_next) == audio->pcm_buf_count) + audio->read_next = 0; + } + } + + if (audio->buf_refresh) { + audio->buf_refresh = 0; + dprintk("audamrnb_read: kick start pcm feedback again\n"); + audamrnb_buffer_refresh(audio); + } + + mutex_unlock(&audio->read_lock); + + if (buf > start) + rc = buf - start; + + dprintk("audamrnb_read: read %d bytes\n", rc); + return rc; +} + +static ssize_t audamrnb_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + struct audio *audio = file->private_data; + const char __user *start = buf; + struct buffer *frame; + size_t xfer; + int rc = 0; + + if (count & 1) + return -EINVAL; + dprintk("audamrnb_write() \n"); + mutex_lock(&audio->write_lock); + while (count > 0) { + frame = audio->out + audio->out_head; + rc = wait_event_interruptible(audio->write_wait, + (frame->used == 0) + || (audio->stopped)); + dprintk("audamrnb_write() buffer available\n"); + if (rc < 0) + break; + if (audio->stopped) { + rc = -EBUSY; + break; + } + xfer = (count > frame->size) ? frame->size : count; + if (copy_from_user(frame->data, buf, xfer)) { + rc = -EFAULT; + break; + } + + frame->used = xfer; + audio->out_head ^= 1; + count -= xfer; + buf += xfer; + + audamrnb_send_data(audio, 0); + + } + mutex_unlock(&audio->write_lock); + if (buf > start) + return buf - start; + return rc; +} + +static int audamrnb_release(struct inode *inode, struct file *file) +{ + struct audio *audio = file->private_data; + + dprintk("audamrnb_release()\n"); + + mutex_lock(&audio->lock); + audamrnb_disable(audio); + audamrnb_flush(audio); + audamrnb_flush_pcm_buf(audio); + msm_adsp_put(audio->audplay); + audio->audplay = NULL; + audio->opened = 0; + dma_free_coherent(NULL, DMASZ, audio->data, audio->phys); + audio->data = NULL; + if (audio->read_data != NULL) { + dma_free_coherent(NULL, + audio->in[0].size * audio->pcm_buf_count, + audio->read_data, audio->read_phys); + audio->read_data = NULL; + } + audio->pcm_feedback = 0; + mutex_unlock(&audio->lock); + return 0; +} + +static struct audio the_amrnb_audio; + +static int audamrnb_open(struct inode *inode, struct file *file) +{ + struct audio *audio = &the_amrnb_audio; + int rc; + + mutex_lock(&audio->lock); + + if (audio->opened) { + pr_err("audio: busy\n"); + rc = -EBUSY; + goto done; + } + + if (!audio->data) { + audio->data = dma_alloc_coherent(NULL, DMASZ, + &audio->phys, GFP_KERNEL); + if (!audio->data) { + pr_err("audio: could not allocate DMA buffers\n"); + rc = -ENOMEM; + goto done; + } + } + + rc = audmgr_open(&audio->audmgr); + if (rc) + goto done; + + rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay, + &audplay_adsp_ops_amrnb, audio); + if (rc) { + pr_err("audio: failed to get audplay0 dsp module\n"); + audmgr_disable(&audio->audmgr); + dma_free_coherent(NULL, DMASZ, audio->data, audio->phys); + audio->data = NULL; + goto done; + } + + audio->dec_id = 0; + + audio->out[0].data = audio->data + 0; + audio->out[0].addr = audio->phys + 0; + audio->out[0].size = BUFSZ; + + audio->out[1].data = audio->data + BUFSZ; + audio->out[1].addr = audio->phys + BUFSZ; + audio->out[1].size = BUFSZ; + + audio->volume = 0x2000; /* Q13 1.0 */ + + audamrnb_flush(audio); + + file->private_data = audio; + audio->opened = 1; + rc = 0; +done: + mutex_unlock(&audio->lock); + return rc; +} + +static struct file_operations audio_amrnb_fops = { + .owner = THIS_MODULE, + .open = audamrnb_open, + .release = audamrnb_release, + .read = audamrnb_read, + .write = audamrnb_write, + .unlocked_ioctl = audamrnb_ioctl, + .llseek = noop_llseek, +}; + +struct miscdevice audio_amrnb_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_amrnb", + .fops = &audio_amrnb_fops, +}; + +static int __init audamrnb_init(void) +{ + mutex_init(&the_amrnb_audio.lock); + mutex_init(&the_amrnb_audio.write_lock); + mutex_init(&the_amrnb_audio.read_lock); + spin_lock_init(&the_amrnb_audio.dsp_lock); + init_waitqueue_head(&the_amrnb_audio.write_wait); + init_waitqueue_head(&the_amrnb_audio.read_wait); + the_amrnb_audio.read_data = NULL; + return misc_register(&audio_amrnb_misc); +} + +static void __exit audamrnb_exit(void) +{ + misc_deregister(&audio_amrnb_misc); +} + +module_init(audamrnb_init); +module_exit(audamrnb_exit); + +MODULE_DESCRIPTION("MSM AMR-NB driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("QUALCOMM Inc"); diff --git a/trunk/drivers/staging/dream/qdsp5/audio_evrc.c b/trunk/drivers/staging/dream/qdsp5/audio_evrc.c new file mode 100644 index 000000000000..24a892647370 --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/audio_evrc.c @@ -0,0 +1,847 @@ +/* arch/arm/mach-msm/audio_evrc.c + * + * Copyright (c) 2008 QUALCOMM USA, INC. + * + * This code also borrows from audio_aac.c, which is + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, you can find it at http://www.fsf.org. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "audmgr.h" + +#include +#include +#include +#include + +#include "adsp.h" + +#ifdef DEBUG +#define dprintk(format, arg...) \ + printk(KERN_DEBUG format, ## arg) +#else +#define dprintk(format, arg...) do {} while (0) +#endif + +/* Hold 30 packets of 24 bytes each*/ +#define BUFSZ 720 +#define DMASZ (BUFSZ * 2) + +#define AUDDEC_DEC_EVRC 12 + +#define PCM_BUFSZ_MIN 1600 /* 100ms worth of data */ +#define PCM_BUF_MAX_COUNT 5 +/* DSP only accepts 5 buffers at most + * but support 2 buffers currently + */ +#define EVRC_DECODED_FRSZ 320 /* EVRC 20ms 8KHz mono PCM size */ + +#define ROUTING_MODE_FTRT 1 +#define ROUTING_MODE_RT 2 +/* Decoder status received from AUDPPTASK */ +#define AUDPP_DEC_STATUS_SLEEP 0 +#define AUDPP_DEC_STATUS_INIT 1 +#define AUDPP_DEC_STATUS_CFG 2 +#define AUDPP_DEC_STATUS_PLAY 3 + +struct buffer { + void *data; + unsigned size; + unsigned used; /* Input usage actual DSP produced PCM size */ + unsigned addr; +}; + +struct audio { + struct buffer out[2]; + + spinlock_t dsp_lock; + + uint8_t out_head; + uint8_t out_tail; + uint8_t out_needed; /* number of buffers the dsp is waiting for */ + + atomic_t out_bytes; + + struct mutex lock; + struct mutex write_lock; + wait_queue_head_t write_wait; + + /* Host PCM section */ + struct buffer in[PCM_BUF_MAX_COUNT]; + struct mutex read_lock; + wait_queue_head_t read_wait; /* Wait queue for read */ + char *read_data; /* pointer to reader buffer */ + dma_addr_t read_phys; /* physical address of reader buffer */ + uint8_t read_next; /* index to input buffers to be read next */ + uint8_t fill_next; /* index to buffer that DSP should be filling */ + uint8_t pcm_buf_count; /* number of pcm buffer allocated */ + /* ---- End of Host PCM section */ + + struct msm_adsp_module *audplay; + struct audmgr audmgr; + + /* data allocated for various buffers */ + char *data; + dma_addr_t phys; + + uint8_t opened:1; + uint8_t enabled:1; + uint8_t running:1; + uint8_t stopped:1; /* set when stopped, cleared on flush */ + uint8_t pcm_feedback:1; + uint8_t buf_refresh:1; + + unsigned volume; + uint16_t dec_id; + uint32_t read_ptr_offset; +}; +static struct audio the_evrc_audio; + +static int auddec_dsp_config(struct audio *audio, int enable); +static void audpp_cmd_cfg_adec_params(struct audio *audio); +static void audpp_cmd_cfg_routing_mode(struct audio *audio); +static void audevrc_send_data(struct audio *audio, unsigned needed); +static void audevrc_dsp_event(void *private, unsigned id, uint16_t *msg); +static void audevrc_config_hostpcm(struct audio *audio); +static void audevrc_buffer_refresh(struct audio *audio); + +/* must be called with audio->lock held */ +static int audevrc_enable(struct audio *audio) +{ + struct audmgr_config cfg; + int rc; + + if (audio->enabled) + return 0; + + audio->out_tail = 0; + audio->out_needed = 0; + + cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; + cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; + cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK; + cfg.codec = RPC_AUD_DEF_CODEC_EVRC; + cfg.snd_method = RPC_SND_METHOD_MIDI; + + rc = audmgr_enable(&audio->audmgr, &cfg); + if (rc < 0) + return rc; + + if (msm_adsp_enable(audio->audplay)) { + pr_err("audio: msm_adsp_enable(audplay) failed\n"); + audmgr_disable(&audio->audmgr); + return -ENODEV; + } + + if (audpp_enable(audio->dec_id, audevrc_dsp_event, audio)) { + pr_err("audio: audpp_enable() failed\n"); + msm_adsp_disable(audio->audplay); + audmgr_disable(&audio->audmgr); + return -ENODEV; + } + audio->enabled = 1; + return 0; +} + +/* must be called with audio->lock held */ +static int audevrc_disable(struct audio *audio) +{ + if (audio->enabled) { + audio->enabled = 0; + auddec_dsp_config(audio, 0); + wake_up(&audio->write_wait); + wake_up(&audio->read_wait); + msm_adsp_disable(audio->audplay); + audpp_disable(audio->dec_id, audio); + audmgr_disable(&audio->audmgr); + audio->out_needed = 0; + } + return 0; +} + +/* ------------------- dsp --------------------- */ + +static void audevrc_update_pcm_buf_entry(struct audio *audio, + uint32_t *payload) +{ + uint8_t index; + unsigned long flags; + + spin_lock_irqsave(&audio->dsp_lock, flags); + for (index = 0; index < payload[1]; index++) { + if (audio->in[audio->fill_next].addr + == payload[2 + index * 2]) { + dprintk("audevrc_update_pcm_buf_entry: in[%d] ready\n", + audio->fill_next); + audio->in[audio->fill_next].used = + payload[3 + index * 2]; + if ((++audio->fill_next) == audio->pcm_buf_count) + audio->fill_next = 0; + + } else { + pr_err + ("audevrc_update_pcm_buf_entry: expected=%x ret=%x\n", + audio->in[audio->fill_next].addr, + payload[1 + index * 2]); + break; + } + } + if (audio->in[audio->fill_next].used == 0) { + audevrc_buffer_refresh(audio); + } else { + dprintk("audevrc_update_pcm_buf_entry: read cannot keep up\n"); + audio->buf_refresh = 1; + } + + spin_unlock_irqrestore(&audio->dsp_lock, flags); + wake_up(&audio->read_wait); +} + +static void audplay_dsp_event(void *data, unsigned id, size_t len, + void (*getevent) (void *ptr, size_t len)) +{ + struct audio *audio = data; + uint32_t msg[28]; + getevent(msg, sizeof(msg)); + + dprintk("audplay_dsp_event: msg_id=%x\n", id); + switch (id) { + case AUDPLAY_MSG_DEC_NEEDS_DATA: + audevrc_send_data(audio, 1); + break; + case AUDPLAY_MSG_BUFFER_UPDATE: + dprintk("audevrc_update_pcm_buf_entry:======> \n"); + audevrc_update_pcm_buf_entry(audio, msg); + break; + default: + pr_err("unexpected message from decoder \n"); + } +} + +static void audevrc_dsp_event(void *private, unsigned id, uint16_t *msg) +{ + struct audio *audio = private; + + switch (id) { + case AUDPP_MSG_STATUS_MSG:{ + unsigned status = msg[1]; + + switch (status) { + case AUDPP_DEC_STATUS_SLEEP: + dprintk("decoder status: sleep \n"); + break; + + case AUDPP_DEC_STATUS_INIT: + dprintk("decoder status: init \n"); + audpp_cmd_cfg_routing_mode(audio); + break; + + case AUDPP_DEC_STATUS_CFG: + dprintk("decoder status: cfg \n"); + break; + case AUDPP_DEC_STATUS_PLAY: + dprintk("decoder status: play \n"); + if (audio->pcm_feedback) { + audevrc_config_hostpcm(audio); + audevrc_buffer_refresh(audio); + } + break; + default: + pr_err("unknown decoder status \n"); + } + break; + } + case AUDPP_MSG_CFG_MSG: + if (msg[0] == AUDPP_MSG_ENA_ENA) { + dprintk("audevrc_dsp_event: CFG_MSG ENABLE\n"); + auddec_dsp_config(audio, 1); + audio->out_needed = 0; + audio->running = 1; + audpp_set_volume_and_pan(audio->dec_id, audio->volume, + 0); + audpp_avsync(audio->dec_id, 22050); + } else if (msg[0] == AUDPP_MSG_ENA_DIS) { + dprintk("audevrc_dsp_event: CFG_MSG DISABLE\n"); + audpp_avsync(audio->dec_id, 0); + audio->running = 0; + } else { + pr_err("audevrc_dsp_event: CFG_MSG %d?\n", msg[0]); + } + break; + case AUDPP_MSG_ROUTING_ACK: + dprintk("audevrc_dsp_event: ROUTING_ACK\n"); + audpp_cmd_cfg_adec_params(audio); + break; + + default: + pr_err("audevrc_dsp_event: UNKNOWN (%d)\n", id); + } + +} + +struct msm_adsp_ops audplay_adsp_ops_evrc = { + .event = audplay_dsp_event, +}; + +#define audplay_send_queue0(audio, cmd, len) \ + msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \ + cmd, len) + +static int auddec_dsp_config(struct audio *audio, int enable) +{ + audpp_cmd_cfg_dec_type cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE; + if (enable) + cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | + AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_EVRC; + else + cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V; + + return audpp_send_queue1(&cmd, sizeof(cmd)); +} + +static void audpp_cmd_cfg_adec_params(struct audio *audio) +{ + struct audpp_cmd_cfg_adec_params_evrc cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; + cmd.common.length = sizeof(cmd); + cmd.common.dec_id = audio->dec_id; + cmd.common.input_sampling_frequency = 8000; + cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V; + + audpp_send_queue2(&cmd, sizeof(cmd)); +} + +static void audpp_cmd_cfg_routing_mode(struct audio *audio) +{ + struct audpp_cmd_routing_mode cmd; + dprintk("audpp_cmd_cfg_routing_mode()\n"); + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; + cmd.object_number = audio->dec_id; + if (audio->pcm_feedback) + cmd.routing_mode = ROUTING_MODE_FTRT; + else + cmd.routing_mode = ROUTING_MODE_RT; + + audpp_send_queue1(&cmd, sizeof(cmd)); +} + +static int audplay_dsp_send_data_avail(struct audio *audio, + unsigned idx, unsigned len) +{ + audplay_cmd_bitstream_data_avail cmd; + + cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL; + cmd.decoder_id = audio->dec_id; + cmd.buf_ptr = audio->out[idx].addr; + cmd.buf_size = len / 2; + cmd.partition_number = 0; + return audplay_send_queue0(audio, &cmd, sizeof(cmd)); +} + +static void audevrc_buffer_refresh(struct audio *audio) +{ + struct audplay_cmd_buffer_refresh refresh_cmd; + + refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; + refresh_cmd.num_buffers = 1; + refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; + refresh_cmd.buf0_length = audio->in[audio->fill_next].size; + + refresh_cmd.buf_read_count = 0; + dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n", + refresh_cmd.buf0_address, refresh_cmd.buf0_length); + audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); +} + +static void audevrc_config_hostpcm(struct audio *audio) +{ + struct audplay_cmd_hpcm_buf_cfg cfg_cmd; + + dprintk("audevrc_config_hostpcm()\n"); + cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; + cfg_cmd.max_buffers = 1; + cfg_cmd.byte_swap = 0; + cfg_cmd.hostpcm_config = (0x8000) | (0x4000); + cfg_cmd.feedback_frequency = 1; + cfg_cmd.partition_number = 0; + audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); + +} + +static void audevrc_send_data(struct audio *audio, unsigned needed) +{ + struct buffer *frame; + unsigned long flags; + + spin_lock_irqsave(&audio->dsp_lock, flags); + if (!audio->running) + goto done; + + if (needed) { + /* We were called from the callback because the DSP + * requested more data. Note that the DSP does want + * more data, and if a buffer was in-flight, mark it + * as available (since the DSP must now be done with + * it). + */ + audio->out_needed = 1; + frame = audio->out + audio->out_tail; + if (frame->used == 0xffffffff) { + dprintk("frame %d free\n", audio->out_tail); + frame->used = 0; + audio->out_tail ^= 1; + wake_up(&audio->write_wait); + } + } + + if (audio->out_needed) { + /* If the DSP currently wants data and we have a + * buffer available, we will send it and reset + * the needed flag. We'll mark the buffer as in-flight + * so that it won't be recycled until the next buffer + * is requested + */ + + frame = audio->out + audio->out_tail; + if (frame->used) { + BUG_ON(frame->used == 0xffffffff); + dprintk("frame %d busy\n", audio->out_tail); + audplay_dsp_send_data_avail(audio, audio->out_tail, + frame->used); + frame->used = 0xffffffff; + audio->out_needed = 0; + } + } +done: + spin_unlock_irqrestore(&audio->dsp_lock, flags); +} + +/* ------------------- device --------------------- */ + +static void audevrc_flush(struct audio *audio) +{ + audio->out[0].used = 0; + audio->out[1].used = 0; + audio->out_head = 0; + audio->out_tail = 0; + audio->stopped = 0; + atomic_set(&audio->out_bytes, 0); +} + +static void audevrc_flush_pcm_buf(struct audio *audio) +{ + uint8_t index; + + for (index = 0; index < PCM_BUF_MAX_COUNT; index++) + audio->in[index].used = 0; + + audio->read_next = 0; + audio->fill_next = 0; +} + +static long audevrc_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct audio *audio = file->private_data; + int rc = 0; + + dprintk("audevrc_ioctl() cmd = %d\n", cmd); + + if (cmd == AUDIO_GET_STATS) { + struct msm_audio_stats stats; + stats.byte_count = audpp_avsync_byte_count(audio->dec_id); + stats.sample_count = audpp_avsync_sample_count(audio->dec_id); + if (copy_to_user((void *)arg, &stats, sizeof(stats))) + return -EFAULT; + return 0; + } + if (cmd == AUDIO_SET_VOLUME) { + unsigned long flags; + spin_lock_irqsave(&audio->dsp_lock, flags); + audio->volume = arg; + if (audio->running) + audpp_set_volume_and_pan(audio->dec_id, arg, 0); + spin_unlock_irqrestore(&audio->dsp_lock, flags); + return 0; + } + mutex_lock(&audio->lock); + switch (cmd) { + case AUDIO_START: + rc = audevrc_enable(audio); + break; + case AUDIO_STOP: + rc = audevrc_disable(audio); + audio->stopped = 1; + break; + case AUDIO_SET_CONFIG:{ + dprintk("AUDIO_SET_CONFIG not applicable \n"); + break; + } + case AUDIO_GET_CONFIG:{ + struct msm_audio_config config; + config.buffer_size = BUFSZ; + config.buffer_count = 2; + config.sample_rate = 8000; + config.channel_count = 1; + config.unused[0] = 0; + config.unused[1] = 0; + config.unused[2] = 0; + config.unused[3] = 0; + if (copy_to_user((void *)arg, &config, sizeof(config))) + rc = -EFAULT; + else + rc = 0; + break; + } + case AUDIO_GET_PCM_CONFIG:{ + struct msm_audio_pcm_config config; + config.pcm_feedback = 0; + config.buffer_count = PCM_BUF_MAX_COUNT; + config.buffer_size = PCM_BUFSZ_MIN; + if (copy_to_user((void *)arg, &config, sizeof(config))) + rc = -EFAULT; + else + rc = 0; + break; + } + case AUDIO_SET_PCM_CONFIG:{ + struct msm_audio_pcm_config config; + if (copy_from_user + (&config, (void *)arg, sizeof(config))) { + rc = -EFAULT; + break; + } + if ((config.buffer_count > PCM_BUF_MAX_COUNT) || + (config.buffer_count == 1)) + config.buffer_count = PCM_BUF_MAX_COUNT; + + if (config.buffer_size < PCM_BUFSZ_MIN) + config.buffer_size = PCM_BUFSZ_MIN; + + /* Check if pcm feedback is required */ + if ((config.pcm_feedback) && (!audio->read_data)) { + dprintk("audevrc_ioctl: allocate PCM buf %d\n", + config.buffer_count * + config.buffer_size); + audio->read_data = + dma_alloc_coherent(NULL, + config.buffer_size * + config.buffer_count, + &audio->read_phys, + GFP_KERNEL); + if (!audio->read_data) { + pr_err + ("audevrc_ioctl: no mem for pcm buf\n"); + rc = -1; + } else { + uint8_t index; + uint32_t offset = 0; + audio->pcm_feedback = 1; + audio->buf_refresh = 0; + audio->pcm_buf_count = + config.buffer_count; + audio->read_next = 0; + audio->fill_next = 0; + + for (index = 0; + index < config.buffer_count; + index++) { + audio->in[index].data = + audio->read_data + offset; + audio->in[index].addr = + audio->read_phys + offset; + audio->in[index].size = + config.buffer_size; + audio->in[index].used = 0; + offset += config.buffer_size; + } + rc = 0; + } + } else { + rc = 0; + } + break; + } + case AUDIO_PAUSE: + dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg); + rc = audpp_pause(audio->dec_id, (int) arg); + break; + default: + rc = -EINVAL; + } + mutex_unlock(&audio->lock); + return rc; +} + +static ssize_t audevrc_read(struct file *file, char __user *buf, size_t count, + loff_t *pos) +{ + struct audio *audio = file->private_data; + const char __user *start = buf; + int rc = 0; + if (!audio->pcm_feedback) { + return 0; + /* PCM feedback is not enabled. Nothing to read */ + } + mutex_lock(&audio->read_lock); + dprintk("audevrc_read() \n"); + while (count > 0) { + rc = wait_event_interruptible(audio->read_wait, + (audio->in[audio->read_next]. + used > 0) || (audio->stopped)); + dprintk("audevrc_read() wait terminated \n"); + if (rc < 0) + break; + if (audio->stopped) { + rc = -EBUSY; + break; + } + if (count < audio->in[audio->read_next].used) { + /* Read must happen in frame boundary. Since driver does + * not know frame size, read count must be greater or + * equal to size of PCM samples + */ + dprintk("audevrc_read:read stop - partial frame\n"); + break; + } else { + dprintk("audevrc_read: read from in[%d]\n", + audio->read_next); + if (copy_to_user + (buf, audio->in[audio->read_next].data, + audio->in[audio->read_next].used)) { + pr_err("audevrc_read: invalid addr %x \n", + (unsigned int)buf); + rc = -EFAULT; + break; + } + count -= audio->in[audio->read_next].used; + buf += audio->in[audio->read_next].used; + audio->in[audio->read_next].used = 0; + if ((++audio->read_next) == audio->pcm_buf_count) + audio->read_next = 0; + if (audio->in[audio->read_next].used == 0) + break; /* No data ready at this moment + * Exit while loop to prevent + * output thread sleep too long + */ + + } + } + if (audio->buf_refresh) { + audio->buf_refresh = 0; + dprintk("audevrc_read: kick start pcm feedback again\n"); + audevrc_buffer_refresh(audio); + } + mutex_unlock(&audio->read_lock); + if (buf > start) + rc = buf - start; + dprintk("audevrc_read: read %d bytes\n", rc); + return rc; +} + +static ssize_t audevrc_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + struct audio *audio = file->private_data; + const char __user *start = buf; + struct buffer *frame; + size_t xfer; + int rc = 0; + + if (count & 1) + return -EINVAL; + mutex_lock(&audio->write_lock); + dprintk("audevrc_write() \n"); + while (count > 0) { + frame = audio->out + audio->out_head; + rc = wait_event_interruptible(audio->write_wait, + (frame->used == 0) + || (audio->stopped)); + if (rc < 0) + break; + if (audio->stopped) { + rc = -EBUSY; + break; + } + xfer = (count > frame->size) ? frame->size : count; + if (copy_from_user(frame->data, buf, xfer)) { + rc = -EFAULT; + break; + } + + frame->used = xfer; + audio->out_head ^= 1; + count -= xfer; + buf += xfer; + + audevrc_send_data(audio, 0); + + } + mutex_unlock(&audio->write_lock); + if (buf > start) + return buf - start; + return rc; +} + +static int audevrc_release(struct inode *inode, struct file *file) +{ + struct audio *audio = file->private_data; + + dprintk("audevrc_release()\n"); + + mutex_lock(&audio->lock); + audevrc_disable(audio); + audevrc_flush(audio); + audevrc_flush_pcm_buf(audio); + msm_adsp_put(audio->audplay); + audio->audplay = NULL; + audio->opened = 0; + dma_free_coherent(NULL, DMASZ, audio->data, audio->phys); + audio->data = NULL; + if (audio->read_data != NULL) { + dma_free_coherent(NULL, + audio->in[0].size * audio->pcm_buf_count, + audio->read_data, audio->read_phys); + audio->read_data = NULL; + } + audio->pcm_feedback = 0; + mutex_unlock(&audio->lock); + return 0; +} + +static struct audio the_evrc_audio; + +static int audevrc_open(struct inode *inode, struct file *file) +{ + struct audio *audio = &the_evrc_audio; + int rc; + + if (audio->opened) { + pr_err("audio: busy\n"); + return -EBUSY; + } + + /* Acquire Lock */ + mutex_lock(&audio->lock); + + if (!audio->data) { + audio->data = dma_alloc_coherent(NULL, DMASZ, + &audio->phys, GFP_KERNEL); + if (!audio->data) { + pr_err("audio: could not allocate DMA buffers\n"); + rc = -ENOMEM; + goto dma_fail; + } + } + + rc = audmgr_open(&audio->audmgr); + if (rc) + goto audmgr_fail; + + rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay, + &audplay_adsp_ops_evrc, audio); + if (rc) { + pr_err("audio: failed to get audplay0 dsp module\n"); + goto adsp_fail; + } + + audio->dec_id = 0; + + audio->out[0].data = audio->data + 0; + audio->out[0].addr = audio->phys + 0; + audio->out[0].size = BUFSZ; + + audio->out[1].data = audio->data + BUFSZ; + audio->out[1].addr = audio->phys + BUFSZ; + audio->out[1].size = BUFSZ; + + audio->volume = 0x3FFF; + + audevrc_flush(audio); + + audio->opened = 1; + file->private_data = audio; + + mutex_unlock(&audio->lock); + return rc; + +adsp_fail: + audmgr_close(&audio->audmgr); +audmgr_fail: + dma_free_coherent(NULL, DMASZ, audio->data, audio->phys); +dma_fail: + mutex_unlock(&audio->lock); + return rc; +} + +static struct file_operations audio_evrc_fops = { + .owner = THIS_MODULE, + .open = audevrc_open, + .release = audevrc_release, + .read = audevrc_read, + .write = audevrc_write, + .unlocked_ioctl = audevrc_ioctl, + .llseek = noop_llseek, +}; + +struct miscdevice audio_evrc_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_evrc", + .fops = &audio_evrc_fops, +}; + +static int __init audevrc_init(void) +{ + mutex_init(&the_evrc_audio.lock); + mutex_init(&the_evrc_audio.write_lock); + mutex_init(&the_evrc_audio.read_lock); + spin_lock_init(&the_evrc_audio.dsp_lock); + init_waitqueue_head(&the_evrc_audio.write_wait); + init_waitqueue_head(&the_evrc_audio.read_wait); + the_evrc_audio.read_data = NULL; + return misc_register(&audio_evrc_misc); +} + +static void __exit audevrc_exit(void) +{ + misc_deregister(&audio_evrc_misc); +} + +module_init(audevrc_init); +module_exit(audevrc_exit); + +MODULE_DESCRIPTION("MSM EVRC driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("QUALCOMM Inc"); diff --git a/trunk/drivers/staging/dream/qdsp5/audio_in.c b/trunk/drivers/staging/dream/qdsp5/audio_in.c new file mode 100644 index 000000000000..b51fa096074e --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/audio_in.c @@ -0,0 +1,970 @@ +/* arch/arm/mach-msm/qdsp5/audio_in.c + * + * pcm audio input device + * + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include "audmgr.h" + +#include +#include +#include +#include + +/* for queue ids - should be relative to module number*/ +#include "adsp.h" + +/* FRAME_NUM must be a power of two */ +#define FRAME_NUM (8) +#define FRAME_SIZE (2052 * 2) +#define MONO_DATA_SIZE (2048) +#define STEREO_DATA_SIZE (MONO_DATA_SIZE * 2) +#define DMASZ (FRAME_SIZE * FRAME_NUM) + +#define AGC_PARAM_SIZE (20) +#define NS_PARAM_SIZE (6) +#define IIR_PARAM_SIZE (48) +#define DEBUG (0) + +#define AGC_ENABLE 0x0001 +#define NS_ENABLE 0x0002 +#define IIR_ENABLE 0x0004 + +struct tx_agc_config { + uint16_t agc_params[AGC_PARAM_SIZE]; +}; + +struct ns_config { + uint16_t ns_params[NS_PARAM_SIZE]; +}; + +struct tx_iir_filter { + uint16_t num_bands; + uint16_t iir_params[IIR_PARAM_SIZE]; +}; + +struct audpre_cmd_iir_config_type { + uint16_t cmd_id; + uint16_t active_flag; + uint16_t num_bands; + uint16_t iir_params[IIR_PARAM_SIZE]; +}; + +struct buffer { + void *data; + uint32_t size; + uint32_t read; + uint32_t addr; +}; + +struct audio_in { + struct buffer in[FRAME_NUM]; + + spinlock_t dsp_lock; + + atomic_t in_bytes; + + struct mutex lock; + struct mutex read_lock; + wait_queue_head_t wait; + + struct msm_adsp_module *audpre; + struct msm_adsp_module *audrec; + + /* configuration to use on next enable */ + uint32_t samp_rate; + uint32_t channel_mode; + uint32_t buffer_size; /* 2048 for mono, 4096 for stereo */ + uint32_t type; /* 0 for PCM ,1 for AAC */ + uint32_t dsp_cnt; + uint32_t in_head; /* next buffer dsp will write */ + uint32_t in_tail; /* next buffer read() will read */ + uint32_t in_count; /* number of buffers available to read() */ + + unsigned short samp_rate_index; + + struct audmgr audmgr; + + /* data allocated for various buffers */ + char *data; + dma_addr_t phys; + + int opened; + int enabled; + int running; + int stopped; /* set when stopped, cleared on flush */ + + /* audpre settings */ + int agc_enable; + struct tx_agc_config agc; + + int ns_enable; + struct ns_config ns; + + int iir_enable; + struct tx_iir_filter iir; +}; + +static int audio_in_dsp_enable(struct audio_in *audio, int enable); +static int audio_in_encoder_config(struct audio_in *audio); +static int audio_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt); +static void audio_flush(struct audio_in *audio); +static int audio_dsp_set_agc(struct audio_in *audio); +static int audio_dsp_set_ns(struct audio_in *audio); +static int audio_dsp_set_tx_iir(struct audio_in *audio); + +static unsigned convert_dsp_samp_index(unsigned index) +{ + switch (index) { + case 48000: return AUDREC_CMD_SAMP_RATE_INDX_48000; + case 44100: return AUDREC_CMD_SAMP_RATE_INDX_44100; + case 32000: return AUDREC_CMD_SAMP_RATE_INDX_32000; + case 24000: return AUDREC_CMD_SAMP_RATE_INDX_24000; + case 22050: return AUDREC_CMD_SAMP_RATE_INDX_22050; + case 16000: return AUDREC_CMD_SAMP_RATE_INDX_16000; + case 12000: return AUDREC_CMD_SAMP_RATE_INDX_12000; + case 11025: return AUDREC_CMD_SAMP_RATE_INDX_11025; + case 8000: return AUDREC_CMD_SAMP_RATE_INDX_8000; + default: return AUDREC_CMD_SAMP_RATE_INDX_11025; + } +} + +static unsigned convert_samp_rate(unsigned hz) +{ + switch (hz) { + case 48000: return RPC_AUD_DEF_SAMPLE_RATE_48000; + case 44100: return RPC_AUD_DEF_SAMPLE_RATE_44100; + case 32000: return RPC_AUD_DEF_SAMPLE_RATE_32000; + case 24000: return RPC_AUD_DEF_SAMPLE_RATE_24000; + case 22050: return RPC_AUD_DEF_SAMPLE_RATE_22050; + case 16000: return RPC_AUD_DEF_SAMPLE_RATE_16000; + case 12000: return RPC_AUD_DEF_SAMPLE_RATE_12000; + case 11025: return RPC_AUD_DEF_SAMPLE_RATE_11025; + case 8000: return RPC_AUD_DEF_SAMPLE_RATE_8000; + default: return RPC_AUD_DEF_SAMPLE_RATE_11025; + } +} + +static unsigned convert_samp_index(unsigned index) +{ + switch (index) { + case RPC_AUD_DEF_SAMPLE_RATE_48000: return 48000; + case RPC_AUD_DEF_SAMPLE_RATE_44100: return 44100; + case RPC_AUD_DEF_SAMPLE_RATE_32000: return 32000; + case RPC_AUD_DEF_SAMPLE_RATE_24000: return 24000; + case RPC_AUD_DEF_SAMPLE_RATE_22050: return 22050; + case RPC_AUD_DEF_SAMPLE_RATE_16000: return 16000; + case RPC_AUD_DEF_SAMPLE_RATE_12000: return 12000; + case RPC_AUD_DEF_SAMPLE_RATE_11025: return 11025; + case RPC_AUD_DEF_SAMPLE_RATE_8000: return 8000; + default: return 11025; + } +} + +/* must be called with audio->lock held */ +static int audio_in_enable(struct audio_in *audio) +{ + struct audmgr_config cfg; + int rc; + + if (audio->enabled) + return 0; + + cfg.tx_rate = audio->samp_rate; + cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; + cfg.def_method = RPC_AUD_DEF_METHOD_RECORD; + if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV) + cfg.codec = RPC_AUD_DEF_CODEC_PCM; + else + cfg.codec = RPC_AUD_DEF_CODEC_AAC; + cfg.snd_method = RPC_SND_METHOD_MIDI; + + rc = audmgr_enable(&audio->audmgr, &cfg); + if (rc < 0) + return rc; + + if (msm_adsp_enable(audio->audpre)) { + pr_err("audrec: msm_adsp_enable(audpre) failed\n"); + return -ENODEV; + } + if (msm_adsp_enable(audio->audrec)) { + pr_err("audrec: msm_adsp_enable(audrec) failed\n"); + return -ENODEV; + } + + audio->enabled = 1; + audio_in_dsp_enable(audio, 1); + + return 0; +} + +/* must be called with audio->lock held */ +static int audio_in_disable(struct audio_in *audio) +{ + if (audio->enabled) { + audio->enabled = 0; + + audio_in_dsp_enable(audio, 0); + + wake_up(&audio->wait); + + msm_adsp_disable(audio->audrec); + msm_adsp_disable(audio->audpre); + audmgr_disable(&audio->audmgr); + } + return 0; +} + +/* ------------------- dsp --------------------- */ +static void audpre_dsp_event(void *data, unsigned id, size_t len, + void (*getevent)(void *ptr, size_t len)) +{ + uint16_t msg[2]; + getevent(msg, sizeof(msg)); + + switch (id) { + case AUDPREPROC_MSG_CMD_CFG_DONE_MSG: + pr_info("audpre: type %d, status_flag %d\n", msg[0], msg[1]); + break; + case AUDPREPROC_MSG_ERROR_MSG_ID: + pr_info("audpre: err_index %d\n", msg[0]); + break; + default: + pr_err("audpre: unknown event %d\n", id); + } +} + +struct audio_frame { + uint16_t count_low; + uint16_t count_high; + uint16_t bytes; + uint16_t unknown; + unsigned char samples[]; +} __attribute__((packed)); + +static void audio_in_get_dsp_frames(struct audio_in *audio) +{ + struct audio_frame *frame; + uint32_t index; + unsigned long flags; + + index = audio->in_head; + + /* XXX check for bogus frame size? */ + + frame = (void *) (((char *)audio->in[index].data) - sizeof(*frame)); + + spin_lock_irqsave(&audio->dsp_lock, flags); + audio->in[index].size = frame->bytes; + + audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); + + /* If overflow, move the tail index foward. */ + if (audio->in_head == audio->in_tail) + audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); + else + audio->in_count++; + + audio_dsp_read_buffer(audio, audio->dsp_cnt++); + spin_unlock_irqrestore(&audio->dsp_lock, flags); + + wake_up(&audio->wait); +} + +static void audrec_dsp_event(void *data, unsigned id, size_t len, + void (*getevent)(void *ptr, size_t len)) +{ + struct audio_in *audio = data; + uint16_t msg[3]; + getevent(msg, sizeof(msg)); + + switch (id) { + case AUDREC_MSG_CMD_CFG_DONE_MSG: + if (msg[0] & AUDREC_MSG_CFG_DONE_TYPE_0_UPDATE) { + if (msg[0] & AUDREC_MSG_CFG_DONE_TYPE_0_ENA) { + pr_info("audpre: CFG ENABLED\n"); + audio_dsp_set_agc(audio); + audio_dsp_set_ns(audio); + audio_dsp_set_tx_iir(audio); + audio_in_encoder_config(audio); + } else { + pr_info("audrec: CFG SLEEP\n"); + audio->running = 0; + } + } else { + pr_info("audrec: CMD_CFG_DONE %x\n", msg[0]); + } + break; + case AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG: { + pr_info("audrec: PARAM CFG DONE\n"); + audio->running = 1; + break; + } + case AUDREC_MSG_FATAL_ERR_MSG: + pr_err("audrec: ERROR %x\n", msg[0]); + break; + case AUDREC_MSG_PACKET_READY_MSG: +/* REC_DBG("type %x, count %d", msg[0], (msg[1] | (msg[2] << 16))); */ + audio_in_get_dsp_frames(audio); + break; + default: + pr_err("audrec: unknown event %d\n", id); + } +} + +struct msm_adsp_ops audpre_adsp_ops = { + .event = audpre_dsp_event, +}; + +struct msm_adsp_ops audrec_adsp_ops = { + .event = audrec_dsp_event, +}; + + +#define audio_send_queue_pre(audio, cmd, len) \ + msm_adsp_write(audio->audpre, QDSP_uPAudPreProcCmdQueue, cmd, len) +#define audio_send_queue_recbs(audio, cmd, len) \ + msm_adsp_write(audio->audrec, QDSP_uPAudRecBitStreamQueue, cmd, len) +#define audio_send_queue_rec(audio, cmd, len) \ + msm_adsp_write(audio->audrec, \ + QDSP_uPAudRecCmdQueue, cmd, len) + +static int audio_dsp_set_agc(struct audio_in *audio) +{ + audpreproc_cmd_cfg_agc_params cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_id = AUDPREPROC_CMD_CFG_AGC_PARAMS; + + if (audio->agc_enable) { + /* cmd.tx_agc_param_mask = 0xFE00 from sample code */ + cmd.tx_agc_param_mask = + (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE) | + (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH) | + (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE) | + (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH) | + (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG) | + (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN) | + (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG); + cmd.tx_agc_enable_flag = + AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA; + memcpy(&cmd.static_gain, &audio->agc.agc_params[0], + sizeof(uint16_t) * 6); + /* cmd.param_mask = 0xFFF0 from sample code */ + cmd.param_mask = + (1 << AUDPREPROC_CMD_PARAM_MASK_RMS_TAY) | + (1 << AUDPREPROC_CMD_PARAM_MASK_RELEASEK) | + (1 << AUDPREPROC_CMD_PARAM_MASK_DELAY) | + (1 << AUDPREPROC_CMD_PARAM_MASK_ATTACKK) | + (1 << AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW) | + (1 << AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST) | + (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK) | + (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_MIN) | + (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_MAX) | + (1 << AUDPREPROC_CMD_PARAM_MASK_LEAK_UP) | + (1 << AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN) | + (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK); + memcpy(&cmd.aig_attackk, &audio->agc.agc_params[6], + sizeof(uint16_t) * 14); + + } else { + cmd.tx_agc_param_mask = + (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG); + cmd.tx_agc_enable_flag = + AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS; + } +#if DEBUG + pr_info("cmd_id = 0x%04x\n", cmd.cmd_id); + pr_info("tx_agc_param_mask = 0x%04x\n", cmd.tx_agc_param_mask); + pr_info("tx_agc_enable_flag = 0x%04x\n", cmd.tx_agc_enable_flag); + pr_info("static_gain = 0x%04x\n", cmd.static_gain); + pr_info("adaptive_gain_flag = 0x%04x\n", cmd.adaptive_gain_flag); + pr_info("expander_th = 0x%04x\n", cmd.expander_th); + pr_info("expander_slope = 0x%04x\n", cmd.expander_slope); + pr_info("compressor_th = 0x%04x\n", cmd.compressor_th); + pr_info("compressor_slope = 0x%04x\n", cmd.compressor_slope); + pr_info("param_mask = 0x%04x\n", cmd.param_mask); + pr_info("aig_attackk = 0x%04x\n", cmd.aig_attackk); + pr_info("aig_leak_down = 0x%04x\n", cmd.aig_leak_down); + pr_info("aig_leak_up = 0x%04x\n", cmd.aig_leak_up); + pr_info("aig_max = 0x%04x\n", cmd.aig_max); + pr_info("aig_min = 0x%04x\n", cmd.aig_min); + pr_info("aig_releasek = 0x%04x\n", cmd.aig_releasek); + pr_info("aig_leakrate_fast = 0x%04x\n", cmd.aig_leakrate_fast); + pr_info("aig_leakrate_slow = 0x%04x\n", cmd.aig_leakrate_slow); + pr_info("attackk_msw = 0x%04x\n", cmd.attackk_msw); + pr_info("attackk_lsw = 0x%04x\n", cmd.attackk_lsw); + pr_info("delay = 0x%04x\n", cmd.delay); + pr_info("releasek_msw = 0x%04x\n", cmd.releasek_msw); + pr_info("releasek_lsw = 0x%04x\n", cmd.releasek_lsw); + pr_info("rms_tav = 0x%04x\n", cmd.rms_tav); +#endif + return audio_send_queue_pre(audio, &cmd, sizeof(cmd)); +} + +static int audio_dsp_set_ns(struct audio_in *audio) +{ + audpreproc_cmd_cfg_ns_params cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_id = AUDPREPROC_CMD_CFG_NS_PARAMS; + + if (audio->ns_enable) { + /* cmd.ec_mode_new is fixed as 0x0064 when enable from sample code */ + cmd.ec_mode_new = + AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA | + AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA | + AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA; + memcpy(&cmd.dens_gamma_n, &audio->ns.ns_params, + sizeof(audio->ns.ns_params)); + } else { + cmd.ec_mode_new = + AUDPREPROC_CMD_EC_MODE_NEW_NLMS_DIS | + AUDPREPROC_CMD_EC_MODE_NEW_DES_DIS | + AUDPREPROC_CMD_EC_MODE_NEW_NS_DIS | + AUDPREPROC_CMD_EC_MODE_NEW_CNI_DIS | + AUDPREPROC_CMD_EC_MODE_NEW_NLES_DIS | + AUDPREPROC_CMD_EC_MODE_NEW_HB_DIS | + AUDPREPROC_CMD_EC_MODE_NEW_VA_DIS | + AUDPREPROC_CMD_EC_MODE_NEW_PCD_DIS | + AUDPREPROC_CMD_EC_MODE_NEW_FEHI_DIS | + AUDPREPROC_CMD_EC_MODE_NEW_NEHI_DIS | + AUDPREPROC_CMD_EC_MODE_NEW_NLPP_DIS | + AUDPREPROC_CMD_EC_MODE_NEW_FNE_DIS | + AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_DIS; + } +#if DEBUG + pr_info("cmd_id = 0x%04x\n", cmd.cmd_id); + pr_info("ec_mode_new = 0x%04x\n", cmd.ec_mode_new); + pr_info("dens_gamma_n = 0x%04x\n", cmd.dens_gamma_n); + pr_info("dens_nfe_block_size = 0x%04x\n", cmd.dens_nfe_block_size); + pr_info("dens_limit_ns = 0x%04x\n", cmd.dens_limit_ns); + pr_info("dens_limit_ns_d = 0x%04x\n", cmd.dens_limit_ns_d); + pr_info("wb_gamma_e = 0x%04x\n", cmd.wb_gamma_e); + pr_info("wb_gamma_n = 0x%04x\n", cmd.wb_gamma_n); +#endif + return audio_send_queue_pre(audio, &cmd, sizeof(cmd)); +} + +static int audio_dsp_set_tx_iir(struct audio_in *audio) +{ + struct audpre_cmd_iir_config_type cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_id = AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS; + + if (audio->iir_enable) { + cmd.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA; + cmd.num_bands = audio->iir.num_bands; + memcpy(&cmd.iir_params, &audio->iir.iir_params, + sizeof(audio->iir.iir_params)); + } else { + cmd.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS; + } +#if DEBUG + pr_info("cmd_id = 0x%04x\n", cmd.cmd_id); + pr_info("active_flag = 0x%04x\n", cmd.active_flag); +#endif + return audio_send_queue_pre(audio, &cmd, sizeof(cmd)); +} + +static int audio_in_dsp_enable(struct audio_in *audio, int enable) +{ + audrec_cmd_cfg cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_id = AUDREC_CMD_CFG; + cmd.type_0 = enable ? AUDREC_CMD_TYPE_0_ENA : AUDREC_CMD_TYPE_0_DIS; + cmd.type_0 |= (AUDREC_CMD_TYPE_0_UPDATE | audio->type); + cmd.type_1 = 0; + + return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); +} + +static int audio_in_encoder_config(struct audio_in *audio) +{ + audrec_cmd_arec0param_cfg cmd; + uint16_t *data = (void *) audio->data; + unsigned n; + + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_id = AUDREC_CMD_AREC0PARAM_CFG; + cmd.ptr_to_extpkt_buffer_msw = audio->phys >> 16; + cmd.ptr_to_extpkt_buffer_lsw = audio->phys; + cmd.buf_len = FRAME_NUM; /* Both WAV and AAC use 8 frames */ + cmd.samp_rate_index = audio->samp_rate_index; + cmd.stereo_mode = audio->channel_mode; /* 0 for mono, 1 for stereo */ + + /* FIXME have no idea why cmd.rec_quality is fixed + * as 0x1C00 from sample code + */ + cmd.rec_quality = 0x1C00; + + /* prepare buffer pointers: + * Mono: 1024 samples + 4 halfword header + * Stereo: 2048 samples + 4 halfword header + * AAC + * Mono/Stere: 768 + 4 halfword header + */ + for (n = 0; n < FRAME_NUM; n++) { + audio->in[n].data = data + 4; + if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV) + data += (4 + (audio->channel_mode ? 2048 : 1024)); + else if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC) + data += (4 + 768); + } + + return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); +} + +static int audio_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt) +{ + audrec_cmd_packet_ext_ptr cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_id = AUDREC_CMD_PACKET_EXT_PTR; + /* Both WAV and AAC use AUDREC_CMD_TYPE_0 */ + cmd.type = AUDREC_CMD_TYPE_0; + cmd.curr_rec_count_msw = read_cnt >> 16; + cmd.curr_rec_count_lsw = read_cnt; + + return audio_send_queue_recbs(audio, &cmd, sizeof(cmd)); +} + +/* ------------------- device --------------------- */ + +static void audio_enable_agc(struct audio_in *audio, int enable) +{ + if (audio->agc_enable != enable) { + audio->agc_enable = enable; + if (audio->running) + audio_dsp_set_agc(audio); + } +} + +static void audio_enable_ns(struct audio_in *audio, int enable) +{ + if (audio->ns_enable != enable) { + audio->ns_enable = enable; + if (audio->running) + audio_dsp_set_ns(audio); + } +} + +static void audio_enable_tx_iir(struct audio_in *audio, int enable) +{ + if (audio->iir_enable != enable) { + audio->iir_enable = enable; + if (audio->running) + audio_dsp_set_tx_iir(audio); + } +} + +static void audio_flush(struct audio_in *audio) +{ + int i; + + audio->dsp_cnt = 0; + audio->in_head = 0; + audio->in_tail = 0; + audio->in_count = 0; + for (i = 0; i < FRAME_NUM; i++) { + audio->in[i].size = 0; + audio->in[i].read = 0; + } +} + +static long audio_in_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct audio_in *audio = file->private_data; + int rc; + + if (cmd == AUDIO_GET_STATS) { + struct msm_audio_stats stats; + stats.byte_count = atomic_read(&audio->in_bytes); + if (copy_to_user((void *) arg, &stats, sizeof(stats))) + return -EFAULT; + return 0; + } + + mutex_lock(&audio->lock); + switch (cmd) { + case AUDIO_START: + rc = audio_in_enable(audio); + break; + case AUDIO_STOP: + rc = audio_in_disable(audio); + audio->stopped = 1; + break; + case AUDIO_FLUSH: + if (audio->stopped) { + /* Make sure we're stopped and we wake any threads + * that might be blocked holding the read_lock. + * While audio->stopped read threads will always + * exit immediately. + */ + wake_up(&audio->wait); + mutex_lock(&audio->read_lock); + audio_flush(audio); + mutex_unlock(&audio->read_lock); + } + case AUDIO_SET_CONFIG: { + struct msm_audio_config cfg; + if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { + rc = -EFAULT; + break; + } + if (cfg.channel_count == 1) { + cfg.channel_count = AUDREC_CMD_STEREO_MODE_MONO; + } else if (cfg.channel_count == 2) { + cfg.channel_count = AUDREC_CMD_STEREO_MODE_STEREO; + } else { + rc = -EINVAL; + break; + } + + if (cfg.type == 0) { + cfg.type = AUDREC_CMD_TYPE_0_INDEX_WAV; + } else if (cfg.type == 1) { + cfg.type = AUDREC_CMD_TYPE_0_INDEX_AAC; + } else { + rc = -EINVAL; + break; + } + audio->samp_rate = convert_samp_rate(cfg.sample_rate); + audio->samp_rate_index = + convert_dsp_samp_index(cfg.sample_rate); + audio->channel_mode = cfg.channel_count; + audio->buffer_size = + audio->channel_mode ? STEREO_DATA_SIZE + : MONO_DATA_SIZE; + audio->type = cfg.type; + rc = 0; + break; + } + case AUDIO_GET_CONFIG: { + struct msm_audio_config cfg; + cfg.buffer_size = audio->buffer_size; + cfg.buffer_count = FRAME_NUM; + cfg.sample_rate = convert_samp_index(audio->samp_rate); + if (audio->channel_mode == AUDREC_CMD_STEREO_MODE_MONO) + cfg.channel_count = 1; + else + cfg.channel_count = 2; + if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV) + cfg.type = 0; + else + cfg.type = 1; + cfg.unused[0] = 0; + cfg.unused[1] = 0; + cfg.unused[2] = 0; + if (copy_to_user((void *) arg, &cfg, sizeof(cfg))) + rc = -EFAULT; + else + rc = 0; + break; + } + default: + rc = -EINVAL; + } + mutex_unlock(&audio->lock); + return rc; +} + +static ssize_t audio_in_read(struct file *file, + char __user *buf, + size_t count, loff_t *pos) +{ + struct audio_in *audio = file->private_data; + unsigned long flags; + const char __user *start = buf; + void *data; + uint32_t index; + uint32_t size; + int rc = 0; + + mutex_lock(&audio->read_lock); + while (count > 0) { + rc = wait_event_interruptible( + audio->wait, (audio->in_count > 0) || audio->stopped); + if (rc < 0) + break; + + if (audio->stopped) { + rc = -EBUSY; + break; + } + + index = audio->in_tail; + data = (uint8_t *) audio->in[index].data; + size = audio->in[index].size; + if (count >= size) { + if (copy_to_user(buf, data, size)) { + rc = -EFAULT; + break; + } + spin_lock_irqsave(&audio->dsp_lock, flags); + if (index != audio->in_tail) { + /* overrun -- data is invalid and we need to retry */ + spin_unlock_irqrestore(&audio->dsp_lock, flags); + continue; + } + audio->in[index].size = 0; + audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); + audio->in_count--; + spin_unlock_irqrestore(&audio->dsp_lock, flags); + count -= size; + buf += size; + if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC) + break; + } else { + pr_err("audio_in: short read\n"); + break; + } + if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC) + break; /* AAC only read one frame */ + } + mutex_unlock(&audio->read_lock); + + if (buf > start) + return buf - start; + + return rc; +} + +static ssize_t audio_in_write(struct file *file, + const char __user *buf, + size_t count, loff_t *pos) +{ + return -EINVAL; +} + +static int audio_in_release(struct inode *inode, struct file *file) +{ + struct audio_in *audio = file->private_data; + + mutex_lock(&audio->lock); + audio_in_disable(audio); + audio_flush(audio); + msm_adsp_put(audio->audrec); + msm_adsp_put(audio->audpre); + audio->audrec = NULL; + audio->audpre = NULL; + audio->opened = 0; + mutex_unlock(&audio->lock); + return 0; +} + +static struct audio_in the_audio_in; + +static int audio_in_open(struct inode *inode, struct file *file) +{ + struct audio_in *audio = &the_audio_in; + int rc; + + mutex_lock(&audio->lock); + if (audio->opened) { + rc = -EBUSY; + goto done; + } + + /* Settings will be re-config at AUDIO_SET_CONFIG, + * but at least we need to have initial config + */ + audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_11025; + audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_11025; + audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO; + audio->buffer_size = MONO_DATA_SIZE; + audio->type = AUDREC_CMD_TYPE_0_INDEX_WAV; + + rc = audmgr_open(&audio->audmgr); + if (rc) + goto done; + rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre, + &audpre_adsp_ops, audio); + if (rc) + goto done; + rc = msm_adsp_get("AUDRECTASK", &audio->audrec, + &audrec_adsp_ops, audio); + if (rc) + goto done; + + audio->dsp_cnt = 0; + audio->stopped = 0; + + audio_flush(audio); + + file->private_data = audio; + audio->opened = 1; + rc = 0; +done: + mutex_unlock(&audio->lock); + return rc; +} + +static long audpre_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct audio_in *audio = file->private_data; + int rc = 0, enable; + uint16_t enable_mask; +#if DEBUG + int i; +#endif + + mutex_lock(&audio->lock); + switch (cmd) { + case AUDIO_ENABLE_AUDPRE: { + if (copy_from_user(&enable_mask, (void *) arg, + sizeof(enable_mask))) + goto out_fault; + + enable = (enable_mask & AGC_ENABLE) ? 1 : 0; + audio_enable_agc(audio, enable); + enable = (enable_mask & NS_ENABLE) ? 1 : 0; + audio_enable_ns(audio, enable); + enable = (enable_mask & IIR_ENABLE) ? 1 : 0; + audio_enable_tx_iir(audio, enable); + break; + } + case AUDIO_SET_AGC: { + if (copy_from_user(&audio->agc, (void *) arg, + sizeof(audio->agc))) + goto out_fault; +#if DEBUG + pr_info("set agc\n"); + for (i = 0; i < AGC_PARAM_SIZE; i++) \ + pr_info("agc_params[%d] = 0x%04x\n", i, + audio->agc.agc_params[i]); +#endif + break; + } + case AUDIO_SET_NS: { + if (copy_from_user(&audio->ns, (void *) arg, + sizeof(audio->ns))) + goto out_fault; +#if DEBUG + pr_info("set ns\n"); + for (i = 0; i < NS_PARAM_SIZE; i++) \ + pr_info("ns_params[%d] = 0x%04x\n", + i, audio->ns.ns_params[i]); +#endif + break; + } + case AUDIO_SET_TX_IIR: { + if (copy_from_user(&audio->iir, (void *) arg, + sizeof(audio->iir))) + goto out_fault; +#if DEBUG + pr_info("set iir\n"); + pr_info("iir.num_bands = 0x%04x\n", audio->iir.num_bands); + for (i = 0; i < IIR_PARAM_SIZE; i++) \ + pr_info("iir_params[%d] = 0x%04x\n", + i, audio->iir.iir_params[i]); +#endif + break; + } + default: + rc = -EINVAL; + } + + goto out; + +out_fault: + rc = -EFAULT; +out: + mutex_unlock(&audio->lock); + return rc; +} + +static int audpre_open(struct inode *inode, struct file *file) +{ + struct audio_in *audio = &the_audio_in; + file->private_data = audio; + return 0; +} + +static struct file_operations audio_fops = { + .owner = THIS_MODULE, + .open = audio_in_open, + .release = audio_in_release, + .read = audio_in_read, + .write = audio_in_write, + .unlocked_ioctl = audio_in_ioctl, + .llseek = noop_llseek, +}; + +static struct file_operations audpre_fops = { + .owner = THIS_MODULE, + .open = audpre_open, + .unlocked_ioctl = audpre_ioctl, + .llseek = noop_llseek, +}; + +struct miscdevice audio_in_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_pcm_in", + .fops = &audio_fops, +}; + +struct miscdevice audpre_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_audpre", + .fops = &audpre_fops, +}; + +static int __init audio_in_init(void) +{ + int rc; + the_audio_in.data = dma_alloc_coherent(NULL, DMASZ, + &the_audio_in.phys, GFP_KERNEL); + if (!the_audio_in.data) { + printk(KERN_ERR "%s: Unable to allocate DMA buffer\n", + __func__); + return -ENOMEM; + } + + mutex_init(&the_audio_in.lock); + mutex_init(&the_audio_in.read_lock); + spin_lock_init(&the_audio_in.dsp_lock); + init_waitqueue_head(&the_audio_in.wait); + rc = misc_register(&audio_in_misc); + if (!rc) { + rc = misc_register(&audpre_misc); + if (rc < 0) + misc_deregister(&audio_in_misc); + } + return rc; +} + +device_initcall(audio_in_init); diff --git a/trunk/drivers/staging/dream/qdsp5/audio_mp3.c b/trunk/drivers/staging/dream/qdsp5/audio_mp3.c new file mode 100644 index 000000000000..409a19ce6039 --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/audio_mp3.c @@ -0,0 +1,972 @@ +/* arch/arm/mach-msm/qdsp5/audio_mp3.c + * + * mp3 audio output device + * + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include "audmgr.h" + +#include +#include +#include +#include + +/* for queue ids - should be relative to module number*/ +#include "adsp.h" + +#ifdef DEBUG +#define dprintk(format, arg...) \ +printk(KERN_DEBUG format, ## arg) +#else +#define dprintk(format, arg...) do {} while (0) +#endif + +/* Size must be power of 2 */ +#define BUFSZ_MAX 32768 +#define BUFSZ_MIN 4096 +#define DMASZ_MAX (BUFSZ_MAX * 2) +#define DMASZ_MIN (BUFSZ_MIN * 2) + +#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF +#define AUDDEC_DEC_MP3 2 + +#define PCM_BUFSZ_MIN 4800 /* Hold one stereo MP3 frame */ +#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most + but support 2 buffers currently */ +#define ROUTING_MODE_FTRT 1 +#define ROUTING_MODE_RT 2 +/* Decoder status received from AUDPPTASK */ +#define AUDPP_DEC_STATUS_SLEEP 0 +#define AUDPP_DEC_STATUS_INIT 1 +#define AUDPP_DEC_STATUS_CFG 2 +#define AUDPP_DEC_STATUS_PLAY 3 + +struct buffer { + void *data; + unsigned size; + unsigned used; /* Input usage actual DSP produced PCM size */ + unsigned addr; +}; + +struct audio { + struct buffer out[2]; + + spinlock_t dsp_lock; + + uint8_t out_head; + uint8_t out_tail; + uint8_t out_needed; /* number of buffers the dsp is waiting for */ + unsigned out_dma_sz; + + atomic_t out_bytes; + + struct mutex lock; + struct mutex write_lock; + wait_queue_head_t write_wait; + + /* Host PCM section */ + struct buffer in[PCM_BUF_MAX_COUNT]; + struct mutex read_lock; + wait_queue_head_t read_wait; /* Wait queue for read */ + char *read_data; /* pointer to reader buffer */ + dma_addr_t read_phys; /* physical address of reader buffer */ + uint8_t read_next; /* index to input buffers to be read next */ + uint8_t fill_next; /* index to buffer that DSP should be filling */ + uint8_t pcm_buf_count; /* number of pcm buffer allocated */ + /* ---- End of Host PCM section */ + + struct msm_adsp_module *audplay; + + /* configuration to use on next enable */ + uint32_t out_sample_rate; + uint32_t out_channel_mode; + + struct audmgr audmgr; + + /* data allocated for various buffers */ + char *data; + dma_addr_t phys; + + int rflush; /* Read flush */ + int wflush; /* Write flush */ + int opened; + int enabled; + int running; + int stopped; /* set when stopped, cleared on flush */ + int pcm_feedback; + int buf_refresh; + + int reserved; /* A byte is being reserved */ + char rsv_byte; /* Handle odd length user data */ + + unsigned volume; + + uint16_t dec_id; + uint32_t read_ptr_offset; +}; + +static int auddec_dsp_config(struct audio *audio, int enable); +static void audpp_cmd_cfg_adec_params(struct audio *audio); +static void audpp_cmd_cfg_routing_mode(struct audio *audio); +static void audplay_send_data(struct audio *audio, unsigned needed); +static void audplay_config_hostpcm(struct audio *audio); +static void audplay_buffer_refresh(struct audio *audio); +static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); + +/* must be called with audio->lock held */ +static int audio_enable(struct audio *audio) +{ + struct audmgr_config cfg; + int rc; + + pr_info("audio_enable()\n"); + + if (audio->enabled) + return 0; + + audio->out_tail = 0; + audio->out_needed = 0; + + cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; + cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; + cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK; + cfg.codec = RPC_AUD_DEF_CODEC_MP3; + cfg.snd_method = RPC_SND_METHOD_MIDI; + + rc = audmgr_enable(&audio->audmgr, &cfg); + if (rc < 0) + return rc; + + if (msm_adsp_enable(audio->audplay)) { + pr_err("audio: msm_adsp_enable(audplay) failed\n"); + audmgr_disable(&audio->audmgr); + return -ENODEV; + } + + if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) { + pr_err("audio: audpp_enable() failed\n"); + msm_adsp_disable(audio->audplay); + audmgr_disable(&audio->audmgr); + return -ENODEV; + } + + audio->enabled = 1; + return 0; +} + +/* must be called with audio->lock held */ +static int audio_disable(struct audio *audio) +{ + pr_info("audio_disable()\n"); + if (audio->enabled) { + audio->enabled = 0; + auddec_dsp_config(audio, 0); + wake_up(&audio->write_wait); + wake_up(&audio->read_wait); + msm_adsp_disable(audio->audplay); + audpp_disable(audio->dec_id, audio); + audmgr_disable(&audio->audmgr); + audio->out_needed = 0; + } + return 0; +} + +/* ------------------- dsp --------------------- */ +static void audio_update_pcm_buf_entry(struct audio *audio, uint32_t *payload) +{ + uint8_t index; + unsigned long flags; + + if (audio->rflush) { + audio->buf_refresh = 1; + return; + } + spin_lock_irqsave(&audio->dsp_lock, flags); + for (index = 0; index < payload[1]; index++) { + if (audio->in[audio->fill_next].addr == + payload[2 + index * 2]) { + pr_info("audio_update_pcm_buf_entry: in[%d] ready\n", + audio->fill_next); + audio->in[audio->fill_next].used = + payload[3 + index * 2]; + if ((++audio->fill_next) == audio->pcm_buf_count) + audio->fill_next = 0; + + } else { + pr_err + ("audio_update_pcm_buf_entry: expected=%x ret=%x\n" + , audio->in[audio->fill_next].addr, + payload[1 + index * 2]); + break; + } + } + if (audio->in[audio->fill_next].used == 0) { + audplay_buffer_refresh(audio); + } else { + pr_info("audio_update_pcm_buf_entry: read cannot keep up\n"); + audio->buf_refresh = 1; + } + wake_up(&audio->read_wait); + spin_unlock_irqrestore(&audio->dsp_lock, flags); + +} + +static void audplay_dsp_event(void *data, unsigned id, size_t len, + void (*getevent) (void *ptr, size_t len)) +{ + struct audio *audio = data; + uint32_t msg[28]; + getevent(msg, sizeof(msg)); + + dprintk("audplay_dsp_event: msg_id=%x\n", id); + + switch (id) { + case AUDPLAY_MSG_DEC_NEEDS_DATA: + audplay_send_data(audio, 1); + break; + + case AUDPLAY_MSG_BUFFER_UPDATE: + audio_update_pcm_buf_entry(audio, msg); + break; + + default: + pr_err("unexpected message from decoder \n"); + break; + } +} + +static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) +{ + struct audio *audio = private; + + switch (id) { + case AUDPP_MSG_STATUS_MSG:{ + unsigned status = msg[1]; + + switch (status) { + case AUDPP_DEC_STATUS_SLEEP: + pr_info("decoder status: sleep \n"); + break; + + case AUDPP_DEC_STATUS_INIT: + pr_info("decoder status: init \n"); + audpp_cmd_cfg_routing_mode(audio); + break; + + case AUDPP_DEC_STATUS_CFG: + pr_info("decoder status: cfg \n"); + break; + case AUDPP_DEC_STATUS_PLAY: + pr_info("decoder status: play \n"); + if (audio->pcm_feedback) { + audplay_config_hostpcm(audio); + audplay_buffer_refresh(audio); + } + break; + default: + pr_err("unknown decoder status \n"); + break; + } + break; + } + case AUDPP_MSG_CFG_MSG: + if (msg[0] == AUDPP_MSG_ENA_ENA) { + pr_info("audio_dsp_event: CFG_MSG ENABLE\n"); + auddec_dsp_config(audio, 1); + audio->out_needed = 0; + audio->running = 1; + audpp_set_volume_and_pan(audio->dec_id, audio->volume, + 0); + audpp_avsync(audio->dec_id, 22050); + } else if (msg[0] == AUDPP_MSG_ENA_DIS) { + pr_info("audio_dsp_event: CFG_MSG DISABLE\n"); + audpp_avsync(audio->dec_id, 0); + audio->running = 0; + } else { + pr_err("audio_dsp_event: CFG_MSG %d?\n", msg[0]); + } + break; + case AUDPP_MSG_ROUTING_ACK: + pr_info("audio_dsp_event: ROUTING_ACK mode=%d\n", msg[1]); + audpp_cmd_cfg_adec_params(audio); + break; + + case AUDPP_MSG_FLUSH_ACK: + dprintk("%s: FLUSH_ACK\n", __func__); + audio->wflush = 0; + audio->rflush = 0; + if (audio->pcm_feedback) + audplay_buffer_refresh(audio); + break; + + default: + pr_err("audio_dsp_event: UNKNOWN (%d)\n", id); + } + +} + + +struct msm_adsp_ops audplay_adsp_ops = { + .event = audplay_dsp_event, +}; + + +#define audplay_send_queue0(audio, cmd, len) \ + msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \ + cmd, len) + +static int auddec_dsp_config(struct audio *audio, int enable) +{ + audpp_cmd_cfg_dec_type cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE; + if (enable) + cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | + AUDPP_CMD_ENA_DEC_V | + AUDDEC_DEC_MP3; + else + cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | + AUDPP_CMD_DIS_DEC_V; + + return audpp_send_queue1(&cmd, sizeof(cmd)); +} + +static void audpp_cmd_cfg_adec_params(struct audio *audio) +{ + audpp_cmd_cfg_adec_params_mp3 cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; + cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN; + cmd.common.dec_id = audio->dec_id; + cmd.common.input_sampling_frequency = audio->out_sample_rate; + + audpp_send_queue2(&cmd, sizeof(cmd)); +} + +static void audpp_cmd_cfg_routing_mode(struct audio *audio) +{ + struct audpp_cmd_routing_mode cmd; + pr_info("audpp_cmd_cfg_routing_mode()\n"); + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; + cmd.object_number = audio->dec_id; + if (audio->pcm_feedback) + cmd.routing_mode = ROUTING_MODE_FTRT; + else + cmd.routing_mode = ROUTING_MODE_RT; + + audpp_send_queue1(&cmd, sizeof(cmd)); +} + +static int audplay_dsp_send_data_avail(struct audio *audio, + unsigned idx, unsigned len) +{ + audplay_cmd_bitstream_data_avail cmd; + + cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL; + cmd.decoder_id = audio->dec_id; + cmd.buf_ptr = audio->out[idx].addr; + cmd.buf_size = len/2; + cmd.partition_number = 0; + return audplay_send_queue0(audio, &cmd, sizeof(cmd)); +} + +static void audplay_buffer_refresh(struct audio *audio) +{ + struct audplay_cmd_buffer_refresh refresh_cmd; + + refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; + refresh_cmd.num_buffers = 1; + refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; + refresh_cmd.buf0_length = audio->in[audio->fill_next].size - + (audio->in[audio->fill_next].size % 576); /* Mp3 frame size */ + refresh_cmd.buf_read_count = 0; + pr_info("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n", + refresh_cmd.buf0_address, refresh_cmd.buf0_length); + (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); +} + +static void audplay_config_hostpcm(struct audio *audio) +{ + struct audplay_cmd_hpcm_buf_cfg cfg_cmd; + + pr_info("audplay_config_hostpcm()\n"); + cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; + cfg_cmd.max_buffers = 1; + cfg_cmd.byte_swap = 0; + cfg_cmd.hostpcm_config = (0x8000) | (0x4000); + cfg_cmd.feedback_frequency = 1; + cfg_cmd.partition_number = 0; + (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); + +} + +static void audplay_send_data(struct audio *audio, unsigned needed) +{ + struct buffer *frame; + unsigned long flags; + + spin_lock_irqsave(&audio->dsp_lock, flags); + if (!audio->running) + goto done; + + if (audio->wflush) { + audio->out_needed = 1; + goto done; + } + + if (needed && !audio->wflush) { + /* We were called from the callback because the DSP + * requested more data. Note that the DSP does want + * more data, and if a buffer was in-flight, mark it + * as available (since the DSP must now be done with + * it). + */ + audio->out_needed = 1; + frame = audio->out + audio->out_tail; + if (frame->used == 0xffffffff) { + dprintk("frame %d free\n", audio->out_tail); + frame->used = 0; + audio->out_tail ^= 1; + wake_up(&audio->write_wait); + } + } + + if (audio->out_needed) { + /* If the DSP currently wants data and we have a + * buffer available, we will send it and reset + * the needed flag. We'll mark the buffer as in-flight + * so that it won't be recycled until the next buffer + * is requested + */ + + frame = audio->out + audio->out_tail; + if (frame->used) { + BUG_ON(frame->used == 0xffffffff); + dprintk("frame %d busy\n", audio->out_tail); + audplay_dsp_send_data_avail(audio, audio->out_tail, + frame->used); + frame->used = 0xffffffff; + audio->out_needed = 0; + } + } +done: + spin_unlock_irqrestore(&audio->dsp_lock, flags); +} + +/* ------------------- device --------------------- */ + +static void audio_flush(struct audio *audio) +{ + audio->out[0].used = 0; + audio->out[1].used = 0; + audio->out_head = 0; + audio->out_tail = 0; + audio->reserved = 0; + atomic_set(&audio->out_bytes, 0); +} + +static void audio_flush_pcm_buf(struct audio *audio) +{ + uint8_t index; + + for (index = 0; index < PCM_BUF_MAX_COUNT; index++) + audio->in[index].used = 0; + + audio->read_next = 0; + audio->fill_next = 0; +} + +static void audio_ioport_reset(struct audio *audio) +{ + /* Make sure read/write thread are free from + * sleep and knowing that system is not able + * to process io request at the moment + */ + wake_up(&audio->write_wait); + mutex_lock(&audio->write_lock); + audio_flush(audio); + mutex_unlock(&audio->write_lock); + wake_up(&audio->read_wait); + mutex_lock(&audio->read_lock); + audio_flush_pcm_buf(audio); + mutex_unlock(&audio->read_lock); +} + +static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct audio *audio = file->private_data; + int rc = 0; + + pr_info("audio_ioctl() cmd = %d\n", cmd); + + if (cmd == AUDIO_GET_STATS) { + struct msm_audio_stats stats; + stats.byte_count = audpp_avsync_byte_count(audio->dec_id); + stats.sample_count = audpp_avsync_sample_count(audio->dec_id); + if (copy_to_user((void *) arg, &stats, sizeof(stats))) + return -EFAULT; + return 0; + } + if (cmd == AUDIO_SET_VOLUME) { + unsigned long flags; + spin_lock_irqsave(&audio->dsp_lock, flags); + audio->volume = arg; + if (audio->running) + audpp_set_volume_and_pan(audio->dec_id, arg, 0); + spin_unlock_irqrestore(&audio->dsp_lock, flags); + return 0; + } + mutex_lock(&audio->lock); + switch (cmd) { + case AUDIO_START: + rc = audio_enable(audio); + break; + case AUDIO_STOP: + rc = audio_disable(audio); + audio->stopped = 1; + audio_ioport_reset(audio); + audio->stopped = 0; + break; + case AUDIO_FLUSH: + dprintk("%s: AUDIO_FLUSH\n", __func__); + audio->rflush = 1; + audio->wflush = 1; + audio_ioport_reset(audio); + audio->rflush = 0; + audio->wflush = 0; + + if (audio->buf_refresh) { + audio->buf_refresh = 0; + audplay_buffer_refresh(audio); + } + break; + + case AUDIO_SET_CONFIG: { + struct msm_audio_config config; + if (copy_from_user(&config, (void *) arg, sizeof(config))) { + rc = -EFAULT; + break; + } + if (config.channel_count == 1) { + config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V; + } else if (config.channel_count == 2) { + config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V; + } else { + rc = -EINVAL; + break; + } + audio->out_sample_rate = config.sample_rate; + audio->out_channel_mode = config.channel_count; + rc = 0; + break; + } + case AUDIO_GET_CONFIG: { + struct msm_audio_config config; + config.buffer_size = (audio->out_dma_sz >> 1); + config.buffer_count = 2; + config.sample_rate = audio->out_sample_rate; + if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) { + config.channel_count = 1; + } else { + config.channel_count = 2; + } + config.unused[0] = 0; + config.unused[1] = 0; + config.unused[2] = 0; + config.unused[3] = 0; + if (copy_to_user((void *) arg, &config, sizeof(config))) { + rc = -EFAULT; + } else { + rc = 0; + } + break; + } + case AUDIO_GET_PCM_CONFIG:{ + struct msm_audio_pcm_config config; + config.pcm_feedback = 0; + config.buffer_count = PCM_BUF_MAX_COUNT; + config.buffer_size = PCM_BUFSZ_MIN; + if (copy_to_user((void *)arg, &config, + sizeof(config))) + rc = -EFAULT; + else + rc = 0; + break; + } + case AUDIO_SET_PCM_CONFIG:{ + struct msm_audio_pcm_config config; + if (copy_from_user + (&config, (void *)arg, sizeof(config))) { + rc = -EFAULT; + break; + } + if ((config.buffer_count > PCM_BUF_MAX_COUNT) || + (config.buffer_count == 1)) + config.buffer_count = PCM_BUF_MAX_COUNT; + + if (config.buffer_size < PCM_BUFSZ_MIN) + config.buffer_size = PCM_BUFSZ_MIN; + + /* Check if pcm feedback is required */ + if ((config.pcm_feedback) && (!audio->read_data)) { + pr_info("ioctl: allocate PCM buffer %d\n", + config.buffer_count * + config.buffer_size); + audio->read_data = + dma_alloc_coherent(NULL, + config.buffer_size * + config.buffer_count, + &audio->read_phys, + GFP_KERNEL); + if (!audio->read_data) { + pr_err("audio_mp3: malloc pcm buf failed\n"); + rc = -1; + } else { + uint8_t index; + uint32_t offset = 0; + audio->pcm_feedback = 1; + audio->buf_refresh = 0; + audio->pcm_buf_count = + config.buffer_count; + audio->read_next = 0; + audio->fill_next = 0; + + for (index = 0; + index < config.buffer_count; + index++) { + audio->in[index].data = + audio->read_data + offset; + audio->in[index].addr = + audio->read_phys + offset; + audio->in[index].size = + config.buffer_size; + audio->in[index].used = 0; + offset += config.buffer_size; + } + rc = 0; + } + } else { + rc = 0; + } + break; + } + case AUDIO_PAUSE: + dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg); + rc = audpp_pause(audio->dec_id, (int) arg); + break; + default: + rc = -EINVAL; + } + mutex_unlock(&audio->lock); + return rc; +} + +static ssize_t audio_read(struct file *file, char __user *buf, size_t count, + loff_t *pos) +{ + struct audio *audio = file->private_data; + const char __user *start = buf; + int rc = 0; + + if (!audio->pcm_feedback) + return 0; /* PCM feedback disabled. Nothing to read */ + + mutex_lock(&audio->read_lock); + pr_info("audio_read() %d \n", count); + while (count > 0) { + rc = wait_event_interruptible(audio->read_wait, + (audio->in[audio->read_next]. + used > 0) || (audio->stopped) + || (audio->rflush)); + + if (rc < 0) + break; + + if (audio->stopped || audio->rflush) { + rc = -EBUSY; + break; + } + + if (count < audio->in[audio->read_next].used) { + /* Read must happen in frame boundary. Since + * driver does not know frame size, read count + * must be greater or equal + * to size of PCM samples + */ + pr_info("audio_read: no partial frame done reading\n"); + break; + } else { + pr_info("audio_read: read from in[%d]\n", + audio->read_next); + if (copy_to_user + (buf, audio->in[audio->read_next].data, + audio->in[audio->read_next].used)) { + pr_err("audio_read: invalid addr %x \n", + (unsigned int)buf); + rc = -EFAULT; + break; + } + count -= audio->in[audio->read_next].used; + buf += audio->in[audio->read_next].used; + audio->in[audio->read_next].used = 0; + if ((++audio->read_next) == audio->pcm_buf_count) + audio->read_next = 0; + if (audio->in[audio->read_next].used == 0) + break; /* No data ready at this moment + * Exit while loop to prevent + * output thread sleep too long + */ + } + } + + /* don't feed output buffer to HW decoder during flushing + * buffer refresh command will be sent once flush completes + * send buf refresh command here can confuse HW decoder + */ + if (audio->buf_refresh && !audio->rflush) { + audio->buf_refresh = 0; + pr_info("audio_read: kick start pcm feedback again\n"); + audplay_buffer_refresh(audio); + } + + mutex_unlock(&audio->read_lock); + + if (buf > start) + rc = buf - start; + + pr_info("audio_read: read %d bytes\n", rc); + return rc; +} + +static ssize_t audio_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + struct audio *audio = file->private_data; + const char __user *start = buf; + struct buffer *frame; + size_t xfer; + char *cpy_ptr; + int rc = 0; + unsigned dsize; + + mutex_lock(&audio->write_lock); + while (count > 0) { + frame = audio->out + audio->out_head; + cpy_ptr = frame->data; + dsize = 0; + rc = wait_event_interruptible(audio->write_wait, + (frame->used == 0) + || (audio->stopped) + || (audio->wflush)); + if (rc < 0) + break; + if (audio->stopped || audio->wflush) { + rc = -EBUSY; + break; + } + + if (audio->reserved) { + dprintk("%s: append reserved byte %x\n", + __func__, audio->rsv_byte); + *cpy_ptr = audio->rsv_byte; + xfer = (count > (frame->size - 1)) ? + frame->size - 1 : count; + cpy_ptr++; + dsize = 1; + audio->reserved = 0; + } else + xfer = (count > frame->size) ? frame->size : count; + + if (copy_from_user(cpy_ptr, buf, xfer)) { + rc = -EFAULT; + break; + } + + dsize += xfer; + if (dsize & 1) { + audio->rsv_byte = ((char *) frame->data)[dsize - 1]; + dprintk("%s: odd length buf reserve last byte %x\n", + __func__, audio->rsv_byte); + audio->reserved = 1; + dsize--; + } + count -= xfer; + buf += xfer; + + if (dsize > 0) { + audio->out_head ^= 1; + frame->used = dsize; + audplay_send_data(audio, 0); + } + } + mutex_unlock(&audio->write_lock); + if (buf > start) + return buf - start; + return rc; +} + +static int audio_release(struct inode *inode, struct file *file) +{ + struct audio *audio = file->private_data; + + dprintk("audio_release()\n"); + + mutex_lock(&audio->lock); + audio_disable(audio); + audio_flush(audio); + audio_flush_pcm_buf(audio); + msm_adsp_put(audio->audplay); + audio->audplay = NULL; + audio->opened = 0; + audio->reserved = 0; + dma_free_coherent(NULL, audio->out_dma_sz, audio->data, audio->phys); + audio->data = NULL; + if (audio->read_data != NULL) { + dma_free_coherent(NULL, + audio->in[0].size * audio->pcm_buf_count, + audio->read_data, audio->read_phys); + audio->read_data = NULL; + } + audio->pcm_feedback = 0; + mutex_unlock(&audio->lock); + return 0; +} + +static struct audio the_mp3_audio; + +static int audio_open(struct inode *inode, struct file *file) +{ + struct audio *audio = &the_mp3_audio; + int rc; + unsigned pmem_sz; + + mutex_lock(&audio->lock); + + if (audio->opened) { + pr_err("audio: busy\n"); + rc = -EBUSY; + goto done; + } + + pmem_sz = DMASZ_MAX; + + while (pmem_sz >= DMASZ_MIN) { + audio->data = dma_alloc_coherent(NULL, pmem_sz, + &audio->phys, GFP_KERNEL); + if (audio->data) + break; + else if (pmem_sz == DMASZ_MIN) { + pr_err("audio: could not allocate DMA buffers\n"); + rc = -ENOMEM; + goto done; + } else + pmem_sz >>= 1; + } + + dprintk("%s: allocated %d bytes DMA buffer\n", __func__, pmem_sz); + + rc = audmgr_open(&audio->audmgr); + if (rc) { + dma_free_coherent(NULL, pmem_sz, + audio->data, audio->phys); + goto done; + } + + rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay, &audplay_adsp_ops, + audio); + if (rc) { + pr_err("audio: failed to get audplay0 dsp module\n"); + dma_free_coherent(NULL, pmem_sz, + audio->data, audio->phys); + audmgr_close(&audio->audmgr); + goto done; + } + + audio->out_dma_sz = pmem_sz; + pmem_sz >>= 1; /* Shift by 1 to get size of ping pong buffer */ + + audio->out_sample_rate = 44100; + audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; + audio->dec_id = 0; + + audio->out[0].data = audio->data + 0; + audio->out[0].addr = audio->phys + 0; + audio->out[0].size = pmem_sz; + + audio->out[1].data = audio->data + pmem_sz; + audio->out[1].addr = audio->phys + pmem_sz; + audio->out[1].size = pmem_sz; + + audio->volume = 0x2000; /* equal to Q13 number 1.0 Unit Gain */ + + audio_flush(audio); + + file->private_data = audio; + audio->opened = 1; + rc = 0; +done: + mutex_unlock(&audio->lock); + return rc; +} + +static struct file_operations audio_mp3_fops = { + .owner = THIS_MODULE, + .open = audio_open, + .release = audio_release, + .read = audio_read, + .write = audio_write, + .unlocked_ioctl = audio_ioctl, + .llseek = noop_llseek, +}; + +struct miscdevice audio_mp3_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_mp3", + .fops = &audio_mp3_fops, +}; + +static int __init audio_init(void) +{ + mutex_init(&the_mp3_audio.lock); + mutex_init(&the_mp3_audio.write_lock); + mutex_init(&the_mp3_audio.read_lock); + spin_lock_init(&the_mp3_audio.dsp_lock); + init_waitqueue_head(&the_mp3_audio.write_wait); + init_waitqueue_head(&the_mp3_audio.read_wait); + the_mp3_audio.read_data = NULL; + return misc_register(&audio_mp3_misc); +} + +device_initcall(audio_init); diff --git a/trunk/drivers/staging/dream/qdsp5/audio_out.c b/trunk/drivers/staging/dream/qdsp5/audio_out.c new file mode 100644 index 000000000000..d20e89541567 --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/audio_out.c @@ -0,0 +1,841 @@ +/* arch/arm/mach-msm/qdsp5/audio_out.c + * + * pcm audio output device + * + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "audmgr.h" + +#include +#include + +#include "evlog.h" + +#define LOG_AUDIO_EVENTS 1 +#define LOG_AUDIO_FAULTS 0 + +enum { + EV_NULL, + EV_OPEN, + EV_WRITE, + EV_RETURN, + EV_IOCTL, + EV_WRITE_WAIT, + EV_WAIT_EVENT, + EV_FILL_BUFFER, + EV_SEND_BUFFER, + EV_DSP_EVENT, + EV_ENABLE, +}; + +#if (LOG_AUDIO_EVENTS != 1) +static inline void LOG(unsigned id, unsigned arg) {} +#else +static const char *pcm_log_strings[] = { + "NULL", + "OPEN", + "WRITE", + "RETURN", + "IOCTL", + "WRITE_WAIT", + "WAIT_EVENT", + "FILL_BUFFER", + "SEND_BUFFER", + "DSP_EVENT", + "ENABLE", +}; + +DECLARE_LOG(pcm_log, 64, pcm_log_strings); + +static int __init _pcm_log_init(void) +{ + return ev_log_init(&pcm_log); +} +module_init(_pcm_log_init); + +#define LOG(id,arg) ev_log_write(&pcm_log, id, arg) +#endif + + + + + +#define BUFSZ (960 * 5) +#define DMASZ (BUFSZ * 2) + +#define AUDPP_CMD_CFG_OBJ_UPDATE 0x8000 +#define AUDPP_CMD_EQ_FLAG_DIS 0x0000 +#define AUDPP_CMD_EQ_FLAG_ENA -1 +#define AUDPP_CMD_IIR_FLAG_DIS 0x0000 +#define AUDPP_CMD_IIR_FLAG_ENA -1 + +#define AUDPP_CMD_IIR_TUNING_FILTER 1 +#define AUDPP_CMD_EQUALIZER 2 +#define AUDPP_CMD_ADRC 3 + +#define ADRC_ENABLE 0x0001 +#define EQ_ENABLE 0x0002 +#define IIR_ENABLE 0x0004 + +struct adrc_filter { + uint16_t compression_th; + uint16_t compression_slope; + uint16_t rms_time; + uint16_t attack_const_lsw; + uint16_t attack_const_msw; + uint16_t release_const_lsw; + uint16_t release_const_msw; + uint16_t adrc_system_delay; +}; + +struct eqalizer { + uint16_t num_bands; + uint16_t eq_params[132]; +}; + +struct rx_iir_filter { + uint16_t num_bands; + uint16_t iir_params[48]; +}; + +typedef struct { + audpp_cmd_cfg_object_params_common common; + uint16_t eq_flag; + uint16_t num_bands; + uint16_t eq_params[132]; +} audpp_cmd_cfg_object_params_eq; + +typedef struct { + audpp_cmd_cfg_object_params_common common; + uint16_t active_flag; + uint16_t num_bands; + uint16_t iir_params[48]; +} audpp_cmd_cfg_object_params_rx_iir; + +struct buffer { + void *data; + unsigned size; + unsigned used; + unsigned addr; +}; + +struct audio { + struct buffer out[2]; + + spinlock_t dsp_lock; + + uint8_t out_head; + uint8_t out_tail; + uint8_t out_needed; /* number of buffers the dsp is waiting for */ + + atomic_t out_bytes; + + struct mutex lock; + struct mutex write_lock; + wait_queue_head_t wait; + + /* configuration to use on next enable */ + uint32_t out_sample_rate; + uint32_t out_channel_mode; + uint32_t out_weight; + uint32_t out_buffer_size; + + struct audmgr audmgr; + + /* data allocated for various buffers */ + char *data; + dma_addr_t phys; + + int opened; + int enabled; + int running; + int stopped; /* set when stopped, cleared on flush */ + unsigned volume; + + int adrc_enable; + struct adrc_filter adrc; + + int eq_enable; + struct eqalizer eq; + + int rx_iir_enable; + struct rx_iir_filter iir; +}; + +static void audio_prevent_sleep(struct audio *audio) +{ + printk(KERN_INFO "++++++++++++++++++++++++++++++\n"); +} + +static void audio_allow_sleep(struct audio *audio) +{ + printk(KERN_INFO "------------------------------\n"); +} + +static int audio_dsp_out_enable(struct audio *audio, int yes); +static int audio_dsp_send_buffer(struct audio *audio, unsigned id, unsigned len); +static int audio_dsp_set_adrc(struct audio *audio); +static int audio_dsp_set_eq(struct audio *audio); +static int audio_dsp_set_rx_iir(struct audio *audio); + +static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); + +/* must be called with audio->lock held */ +static int audio_enable(struct audio *audio) +{ + struct audmgr_config cfg; + int rc; + + pr_info("audio_enable()\n"); + + if (audio->enabled) + return 0; + + /* refuse to start if we're not ready */ + if (!audio->out[0].used || !audio->out[1].used) + return -EIO; + + /* we start buffers 0 and 1, so buffer 0 will be the + * next one the dsp will want + */ + audio->out_tail = 0; + audio->out_needed = 0; + + cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; + cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; + cfg.def_method = RPC_AUD_DEF_METHOD_HOST_PCM; + cfg.codec = RPC_AUD_DEF_CODEC_PCM; + cfg.snd_method = RPC_SND_METHOD_MIDI; + + audio_prevent_sleep(audio); + rc = audmgr_enable(&audio->audmgr, &cfg); + if (rc < 0) { + audio_allow_sleep(audio); + return rc; + } + + if (audpp_enable(-1, audio_dsp_event, audio)) { + pr_err("audio: audpp_enable() failed\n"); + audmgr_disable(&audio->audmgr); + audio_allow_sleep(audio); + return -ENODEV; + } + + audio->enabled = 1; + return 0; +} + +/* must be called with audio->lock held */ +static int audio_disable(struct audio *audio) +{ + pr_info("audio_disable()\n"); + if (audio->enabled) { + audio->enabled = 0; + audio_dsp_out_enable(audio, 0); + + audpp_disable(-1, audio); + + wake_up(&audio->wait); + audmgr_disable(&audio->audmgr); + audio->out_needed = 0; + audio_allow_sleep(audio); + } + return 0; +} + +/* ------------------- dsp --------------------- */ +static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) +{ + struct audio *audio = private; + struct buffer *frame; + unsigned long flags; + + LOG(EV_DSP_EVENT, id); + switch (id) { + case AUDPP_MSG_HOST_PCM_INTF_MSG: { + unsigned id = msg[2]; + unsigned idx = msg[3] - 1; + + /* pr_info("audio_dsp_event: HOST_PCM id %d idx %d\n", id, idx); */ + if (id != AUDPP_MSG_HOSTPCM_ID_ARM_RX) { + pr_err("bogus id\n"); + break; + } + if (idx > 1) { + pr_err("bogus buffer idx\n"); + break; + } + + spin_lock_irqsave(&audio->dsp_lock, flags); + if (audio->running) { + atomic_add(audio->out[idx].used, &audio->out_bytes); + audio->out[idx].used = 0; + + frame = audio->out + audio->out_tail; + if (frame->used) { + audio_dsp_send_buffer( + audio, audio->out_tail, frame->used); + audio->out_tail ^= 1; + } else { + audio->out_needed++; + } + wake_up(&audio->wait); + } + spin_unlock_irqrestore(&audio->dsp_lock, flags); + break; + } + case AUDPP_MSG_PCMDMAMISSED: + pr_info("audio_dsp_event: PCMDMAMISSED %d\n", msg[0]); + break; + case AUDPP_MSG_CFG_MSG: + if (msg[0] == AUDPP_MSG_ENA_ENA) { + LOG(EV_ENABLE, 1); + pr_info("audio_dsp_event: CFG_MSG ENABLE\n"); + audio->out_needed = 0; + audio->running = 1; + audpp_set_volume_and_pan(5, audio->volume, 0); + audio_dsp_set_adrc(audio); + audio_dsp_set_eq(audio); + audio_dsp_set_rx_iir(audio); + audio_dsp_out_enable(audio, 1); + } else if (msg[0] == AUDPP_MSG_ENA_DIS) { + LOG(EV_ENABLE, 0); + pr_info("audio_dsp_event: CFG_MSG DISABLE\n"); + audio->running = 0; + } else { + pr_err("audio_dsp_event: CFG_MSG %d?\n", msg[0]); + } + break; + default: + pr_err("audio_dsp_event: UNKNOWN (%d)\n", id); + } +} + +static int audio_dsp_out_enable(struct audio *audio, int yes) +{ + audpp_cmd_pcm_intf cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_id = AUDPP_CMD_PCM_INTF_2; + cmd.object_num = AUDPP_CMD_PCM_INTF_OBJECT_NUM; + cmd.config = AUDPP_CMD_PCM_INTF_CONFIG_CMD_V; + cmd.intf_type = AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V; + + if (yes) { + cmd.write_buf1LSW = audio->out[0].addr; + cmd.write_buf1MSW = audio->out[0].addr >> 16; + cmd.write_buf1_len = audio->out[0].size; + cmd.write_buf2LSW = audio->out[1].addr; + cmd.write_buf2MSW = audio->out[1].addr >> 16; + cmd.write_buf2_len = audio->out[1].size; + cmd.arm_to_rx_flag = AUDPP_CMD_PCM_INTF_ENA_V; + cmd.weight_decoder_to_rx = audio->out_weight; + cmd.weight_arm_to_rx = 1; + cmd.partition_number_arm_to_dsp = 0; + cmd.sample_rate = audio->out_sample_rate; + cmd.channel_mode = audio->out_channel_mode; + } + + return audpp_send_queue2(&cmd, sizeof(cmd)); +} + +static int audio_dsp_send_buffer(struct audio *audio, unsigned idx, unsigned len) +{ + audpp_cmd_pcm_intf_send_buffer cmd; + + cmd.cmd_id = AUDPP_CMD_PCM_INTF_2; + cmd.host_pcm_object = AUDPP_CMD_PCM_INTF_OBJECT_NUM; + cmd.config = AUDPP_CMD_PCM_INTF_BUFFER_CMD_V; + cmd.intf_type = AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V; + cmd.dsp_to_arm_buf_id = 0; + cmd.arm_to_dsp_buf_id = idx + 1; + cmd.arm_to_dsp_buf_len = len; + + LOG(EV_SEND_BUFFER, idx); + return audpp_send_queue2(&cmd, sizeof(cmd)); +} + +static int audio_dsp_set_adrc(struct audio *audio) +{ + audpp_cmd_cfg_object_params_adrc cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; + cmd.common.command_type = AUDPP_CMD_ADRC; + + if (audio->adrc_enable) { + cmd.adrc_flag = AUDPP_CMD_ADRC_FLAG_ENA; + cmd.compression_th = audio->adrc.compression_th; + cmd.compression_slope = audio->adrc.compression_slope; + cmd.rms_time = audio->adrc.rms_time; + cmd.attack_const_lsw = audio->adrc.attack_const_lsw; + cmd.attack_const_msw = audio->adrc.attack_const_msw; + cmd.release_const_lsw = audio->adrc.release_const_lsw; + cmd.release_const_msw = audio->adrc.release_const_msw; + cmd.adrc_system_delay = audio->adrc.adrc_system_delay; + } else { + cmd.adrc_flag = AUDPP_CMD_ADRC_FLAG_DIS; + } + return audpp_send_queue3(&cmd, sizeof(cmd)); +} + +static int audio_dsp_set_eq(struct audio *audio) +{ + audpp_cmd_cfg_object_params_eq cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; + cmd.common.command_type = AUDPP_CMD_EQUALIZER; + + if (audio->eq_enable) { + cmd.eq_flag = AUDPP_CMD_EQ_FLAG_ENA; + cmd.num_bands = audio->eq.num_bands; + memcpy(&cmd.eq_params, audio->eq.eq_params, + sizeof(audio->eq.eq_params)); + } else { + cmd.eq_flag = AUDPP_CMD_EQ_FLAG_DIS; + } + return audpp_send_queue3(&cmd, sizeof(cmd)); +} + +static int audio_dsp_set_rx_iir(struct audio *audio) +{ + audpp_cmd_cfg_object_params_rx_iir cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; + cmd.common.command_type = AUDPP_CMD_IIR_TUNING_FILTER; + + if (audio->rx_iir_enable) { + cmd.active_flag = AUDPP_CMD_IIR_FLAG_ENA; + cmd.num_bands = audio->iir.num_bands; + memcpy(&cmd.iir_params, audio->iir.iir_params, + sizeof(audio->iir.iir_params)); + } else { + cmd.active_flag = AUDPP_CMD_IIR_FLAG_DIS; + } + + return audpp_send_queue3(&cmd, sizeof(cmd)); +} + +/* ------------------- device --------------------- */ + +static int audio_enable_adrc(struct audio *audio, int enable) +{ + if (audio->adrc_enable != enable) { + audio->adrc_enable = enable; + if (audio->running) + audio_dsp_set_adrc(audio); + } + return 0; +} + +static int audio_enable_eq(struct audio *audio, int enable) +{ + if (audio->eq_enable != enable) { + audio->eq_enable = enable; + if (audio->running) + audio_dsp_set_eq(audio); + } + return 0; +} + +static int audio_enable_rx_iir(struct audio *audio, int enable) +{ + if (audio->rx_iir_enable != enable) { + audio->rx_iir_enable = enable; + if (audio->running) + audio_dsp_set_rx_iir(audio); + } + return 0; +} + +static void audio_flush(struct audio *audio) +{ + audio->out[0].used = 0; + audio->out[1].used = 0; + audio->out_head = 0; + audio->out_tail = 0; + audio->stopped = 0; +} + +static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct audio *audio = file->private_data; + int rc; + + if (cmd == AUDIO_GET_STATS) { + struct msm_audio_stats stats; + stats.byte_count = atomic_read(&audio->out_bytes); + if (copy_to_user((void*) arg, &stats, sizeof(stats))) + return -EFAULT; + return 0; + } + if (cmd == AUDIO_SET_VOLUME) { + unsigned long flags; + spin_lock_irqsave(&audio->dsp_lock, flags); + audio->volume = arg; + if (audio->running) + audpp_set_volume_and_pan(6, arg, 0); + spin_unlock_irqrestore(&audio->dsp_lock, flags); + } + + LOG(EV_IOCTL, cmd); + mutex_lock(&audio->lock); + switch (cmd) { + case AUDIO_START: + rc = audio_enable(audio); + break; + case AUDIO_STOP: + rc = audio_disable(audio); + audio->stopped = 1; + break; + case AUDIO_FLUSH: + if (audio->stopped) { + /* Make sure we're stopped and we wake any threads + * that might be blocked holding the write_lock. + * While audio->stopped write threads will always + * exit immediately. + */ + wake_up(&audio->wait); + mutex_lock(&audio->write_lock); + audio_flush(audio); + mutex_unlock(&audio->write_lock); + } + case AUDIO_SET_CONFIG: { + struct msm_audio_config config; + if (copy_from_user(&config, (void*) arg, sizeof(config))) { + rc = -EFAULT; + break; + } + if (config.channel_count == 1) { + config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V; + } else if (config.channel_count == 2) { + config.channel_count= AUDPP_CMD_PCM_INTF_STEREO_V; + } else { + rc = -EINVAL; + break; + } + audio->out_sample_rate = config.sample_rate; + audio->out_channel_mode = config.channel_count; + rc = 0; + break; + } + case AUDIO_GET_CONFIG: { + struct msm_audio_config config; + config.buffer_size = BUFSZ; + config.buffer_count = 2; + config.sample_rate = audio->out_sample_rate; + if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) { + config.channel_count = 1; + } else { + config.channel_count = 2; + } + config.unused[0] = 0; + config.unused[1] = 0; + config.unused[2] = 0; + config.unused[3] = 0; + if (copy_to_user((void*) arg, &config, sizeof(config))) { + rc = -EFAULT; + } else { + rc = 0; + } + break; + } + default: + rc = -EINVAL; + } + mutex_unlock(&audio->lock); + return rc; +} + +static ssize_t audio_read(struct file *file, char __user *buf, size_t count, loff_t *pos) +{ + return -EINVAL; +} + +static inline int rt_policy(int policy) +{ + if (unlikely(policy == SCHED_FIFO) || unlikely(policy == SCHED_RR)) + return 1; + return 0; +} + +static inline int task_has_rt_policy(struct task_struct *p) +{ + return rt_policy(p->policy); +} + +static ssize_t audio_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + struct sched_param s = { .sched_priority = 1 }; + struct audio *audio = file->private_data; + unsigned long flags; + const char __user *start = buf; + struct buffer *frame; + size_t xfer; + int old_prio = current->rt_priority; + int old_policy = current->policy; + int cap_nice = cap_raised(current_cap(), CAP_SYS_NICE); + int rc = 0; + + LOG(EV_WRITE, count | (audio->running << 28) | (audio->stopped << 24)); + + /* just for this write, set us real-time */ + if (!task_has_rt_policy(current)) { + struct cred *new = prepare_creds(); + cap_raise(new->cap_effective, CAP_SYS_NICE); + commit_creds(new); + sched_setscheduler(current, SCHED_RR, &s); + } + + mutex_lock(&audio->write_lock); + while (count > 0) { + frame = audio->out + audio->out_head; + + LOG(EV_WAIT_EVENT, 0); + rc = wait_event_interruptible(audio->wait, + (frame->used == 0) || (audio->stopped)); + LOG(EV_WAIT_EVENT, 1); + + if (rc < 0) + break; + if (audio->stopped) { + rc = -EBUSY; + break; + } + xfer = count > frame->size ? frame->size : count; + if (copy_from_user(frame->data, buf, xfer)) { + rc = -EFAULT; + break; + } + frame->used = xfer; + audio->out_head ^= 1; + count -= xfer; + buf += xfer; + + spin_lock_irqsave(&audio->dsp_lock, flags); + LOG(EV_FILL_BUFFER, audio->out_head ^ 1); + frame = audio->out + audio->out_tail; + if (frame->used && audio->out_needed) { + audio_dsp_send_buffer(audio, audio->out_tail, frame->used); + audio->out_tail ^= 1; + audio->out_needed--; + } + spin_unlock_irqrestore(&audio->dsp_lock, flags); + } + + mutex_unlock(&audio->write_lock); + + /* restore scheduling policy and priority */ + if (!rt_policy(old_policy)) { + struct sched_param v = { .sched_priority = old_prio }; + sched_setscheduler(current, old_policy, &v); + if (likely(!cap_nice)) { + struct cred *new = prepare_creds(); + cap_lower(new->cap_effective, CAP_SYS_NICE); + commit_creds(new); + sched_setscheduler(current, SCHED_RR, &s); + } + } + + LOG(EV_RETURN,(buf > start) ? (buf - start) : rc); + if (buf > start) + return buf - start; + return rc; +} + +static int audio_release(struct inode *inode, struct file *file) +{ + struct audio *audio = file->private_data; + + LOG(EV_OPEN, 0); + mutex_lock(&audio->lock); + audio_disable(audio); + audio_flush(audio); + audio->opened = 0; + mutex_unlock(&audio->lock); + return 0; +} + +static struct audio the_audio; + +static int audio_open(struct inode *inode, struct file *file) +{ + struct audio *audio = &the_audio; + int rc; + + mutex_lock(&audio->lock); + + if (audio->opened) { + pr_err("audio: busy\n"); + rc = -EBUSY; + goto done; + } + + if (!audio->data) { + audio->data = dma_alloc_coherent(NULL, DMASZ, + &audio->phys, GFP_KERNEL); + if (!audio->data) { + pr_err("audio: could not allocate DMA buffers\n"); + rc = -ENOMEM; + goto done; + } + } + + rc = audmgr_open(&audio->audmgr); + if (rc) + goto done; + + audio->out_buffer_size = BUFSZ; + audio->out_sample_rate = 44100; + audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; + audio->out_weight = 100; + + audio->out[0].data = audio->data + 0; + audio->out[0].addr = audio->phys + 0; + audio->out[0].size = BUFSZ; + + audio->out[1].data = audio->data + BUFSZ; + audio->out[1].addr = audio->phys + BUFSZ; + audio->out[1].size = BUFSZ; + + audio->volume = 0x2000; + + audio_flush(audio); + + file->private_data = audio; + audio->opened = 1; + rc = 0; + LOG(EV_OPEN, 1); +done: + mutex_unlock(&audio->lock); + return rc; +} + +static long audpp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct audio *audio = file->private_data; + int rc = 0, enable; + uint16_t enable_mask; + + mutex_lock(&audio->lock); + switch (cmd) { + case AUDIO_ENABLE_AUDPP: + if (copy_from_user(&enable_mask, (void *) arg, sizeof(enable_mask))) + goto out_fault; + + enable = (enable_mask & ADRC_ENABLE)? 1 : 0; + audio_enable_adrc(audio, enable); + enable = (enable_mask & EQ_ENABLE)? 1 : 0; + audio_enable_eq(audio, enable); + enable = (enable_mask & IIR_ENABLE)? 1 : 0; + audio_enable_rx_iir(audio, enable); + break; + + case AUDIO_SET_ADRC: + if (copy_from_user(&audio->adrc, (void*) arg, sizeof(audio->adrc))) + goto out_fault; + break; + + case AUDIO_SET_EQ: + if (copy_from_user(&audio->eq, (void*) arg, sizeof(audio->eq))) + goto out_fault; + break; + + case AUDIO_SET_RX_IIR: + if (copy_from_user(&audio->iir, (void*) arg, sizeof(audio->iir))) + goto out_fault; + break; + + default: + rc = -EINVAL; + } + + goto out; + + out_fault: + rc = -EFAULT; + out: + mutex_unlock(&audio->lock); + return rc; +} + +static int audpp_open(struct inode *inode, struct file *file) +{ + struct audio *audio = &the_audio; + + file->private_data = audio; + return 0; +} + +static struct file_operations audio_fops = { + .owner = THIS_MODULE, + .open = audio_open, + .release = audio_release, + .read = audio_read, + .write = audio_write, + .unlocked_ioctl = audio_ioctl, + .llseek = noop_llseek, +}; + +static struct file_operations audpp_fops = { + .owner = THIS_MODULE, + .open = audpp_open, + .unlocked_ioctl = audpp_ioctl, + .llseek = noop_llseek, +}; + +struct miscdevice audio_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_pcm_out", + .fops = &audio_fops, +}; + +struct miscdevice audpp_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_pcm_ctl", + .fops = &audpp_fops, +}; + +static int __init audio_init(void) +{ + mutex_init(&the_audio.lock); + mutex_init(&the_audio.write_lock); + spin_lock_init(&the_audio.dsp_lock); + init_waitqueue_head(&the_audio.wait); + return (misc_register(&audio_misc) || misc_register(&audpp_misc)); +} + +device_initcall(audio_init); diff --git a/trunk/drivers/staging/dream/qdsp5/audio_qcelp.c b/trunk/drivers/staging/dream/qdsp5/audio_qcelp.c new file mode 100644 index 000000000000..911bab416b85 --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/audio_qcelp.c @@ -0,0 +1,858 @@ +/* arch/arm/mach-msm/qdsp5/audio_qcelp.c + * + * qcelp 13k audio decoder device + * + * Copyright (c) 2008 QUALCOMM USA, INC. + * + * This code is based in part on audio_mp3.c, which is + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, you can find it at http://www.fsf.org. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "audmgr.h" +/* for queue ids - should be relative to module number*/ +#include "adsp.h" + +#ifdef DEBUG +#define dprintk(format, arg...) \ +printk(KERN_DEBUG format, ## arg) +#else +#define dprintk(format, arg...) do {} while (0) +#endif + +#define BUFSZ 1080 /* QCELP 13K Hold 600ms packet data = 36 * 30 */ +#define BUF_COUNT 2 +#define DMASZ (BUFSZ * BUF_COUNT) + +#define PCM_BUFSZ_MIN 1600 /* 100ms worth of data */ +#define PCM_BUF_MAX_COUNT 5 + +#define AUDDEC_DEC_QCELP 9 + +#define ROUTING_MODE_FTRT 1 +#define ROUTING_MODE_RT 2 +/* Decoder status received from AUDPPTASK */ +#define AUDPP_DEC_STATUS_SLEEP 0 +#define AUDPP_DEC_STATUS_INIT 1 +#define AUDPP_DEC_STATUS_CFG 2 +#define AUDPP_DEC_STATUS_PLAY 3 + +struct buffer { + void *data; + unsigned size; + unsigned used; /* Input usage actual DSP produced PCM size */ + unsigned addr; +}; + +struct audio { + struct buffer out[BUF_COUNT]; + + spinlock_t dsp_lock; + + uint8_t out_head; + uint8_t out_tail; + uint8_t out_needed; /* number of buffers the dsp is waiting for */ + + struct mutex lock; + struct mutex write_lock; + wait_queue_head_t write_wait; + + /* Host PCM section - START */ + struct buffer in[PCM_BUF_MAX_COUNT]; + struct mutex read_lock; + wait_queue_head_t read_wait; /* Wait queue for read */ + char *read_data; /* pointer to reader buffer */ + dma_addr_t read_phys; /* physical address of reader buffer */ + uint8_t read_next; /* index to input buffers to be read next */ + uint8_t fill_next; /* index to buffer that DSP should be filling */ + uint8_t pcm_buf_count; /* number of pcm buffer allocated */ + /* Host PCM section - END */ + + struct msm_adsp_module *audplay; + + struct audmgr audmgr; + + /* data allocated for various buffers */ + char *data; + dma_addr_t phys; + + uint8_t opened:1; + uint8_t enabled:1; + uint8_t running:1; + uint8_t stopped:1; /* set when stopped, cleared on flush */ + uint8_t pcm_feedback:1; /* set when non-tunnel mode */ + uint8_t buf_refresh:1; + + unsigned volume; + + uint16_t dec_id; +}; + +static struct audio the_qcelp_audio; + +static int auddec_dsp_config(struct audio *audio, int enable); +static void audpp_cmd_cfg_adec_params(struct audio *audio); +static void audpp_cmd_cfg_routing_mode(struct audio *audio); +static void audqcelp_send_data(struct audio *audio, unsigned needed); +static void audqcelp_config_hostpcm(struct audio *audio); +static void audqcelp_buffer_refresh(struct audio *audio); +static void audqcelp_dsp_event(void *private, unsigned id, uint16_t *msg); + +/* must be called with audio->lock held */ +static int audqcelp_enable(struct audio *audio) +{ + struct audmgr_config cfg; + int rc; + + dprintk("audqcelp_enable()\n"); + + if (audio->enabled) + return 0; + + audio->out_tail = 0; + audio->out_needed = 0; + + cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; + cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; + cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK; + cfg.codec = RPC_AUD_DEF_CODEC_13K; + cfg.snd_method = RPC_SND_METHOD_MIDI; + + rc = audmgr_enable(&audio->audmgr, &cfg); + if (rc < 0) + return rc; + + if (msm_adsp_enable(audio->audplay)) { + pr_err("audio: msm_adsp_enable(audplay) failed\n"); + audmgr_disable(&audio->audmgr); + return -ENODEV; + } + + if (audpp_enable(audio->dec_id, audqcelp_dsp_event, audio)) { + pr_err("audio: audpp_enable() failed\n"); + msm_adsp_disable(audio->audplay); + audmgr_disable(&audio->audmgr); + return -ENODEV; + } + audio->enabled = 1; + return 0; +} + +/* must be called with audio->lock held */ +static int audqcelp_disable(struct audio *audio) +{ + dprintk("audqcelp_disable()\n"); + if (audio->enabled) { + audio->enabled = 0; + auddec_dsp_config(audio, 0); + wake_up(&audio->write_wait); + wake_up(&audio->read_wait); + msm_adsp_disable(audio->audplay); + audpp_disable(audio->dec_id, audio); + audmgr_disable(&audio->audmgr); + audio->out_needed = 0; + } + return 0; +} + +/* ------------------- dsp --------------------- */ +static void audqcelp_update_pcm_buf_entry(struct audio *audio, + uint32_t *payload) +{ + uint8_t index; + unsigned long flags; + + spin_lock_irqsave(&audio->dsp_lock, flags); + for (index = 0; index < payload[1]; index++) { + if (audio->in[audio->fill_next].addr == + payload[2 + index * 2]) { + dprintk("audqcelp_update_pcm_buf_entry: in[%d] ready\n", + audio->fill_next); + audio->in[audio->fill_next].used = + payload[3 + index * 2]; + if ((++audio->fill_next) == audio->pcm_buf_count) + audio->fill_next = 0; + } else { + pr_err( + "audqcelp_update_pcm_buf_entry: expected=%x ret=%x\n", + audio->in[audio->fill_next].addr, + payload[1 + index * 2]); + break; + } + } + if (audio->in[audio->fill_next].used == 0) { + audqcelp_buffer_refresh(audio); + } else { + dprintk("audqcelp_update_pcm_buf_entry: read cannot keep up\n"); + audio->buf_refresh = 1; + } + + spin_unlock_irqrestore(&audio->dsp_lock, flags); + wake_up(&audio->read_wait); +} + +static void audplay_dsp_event(void *data, unsigned id, size_t len, + void (*getevent) (void *ptr, size_t len)) +{ + struct audio *audio = data; + uint32_t msg[28]; + getevent(msg, sizeof(msg)); + + dprintk("audplay_dsp_event: msg_id=%x\n", id); + + switch (id) { + case AUDPLAY_MSG_DEC_NEEDS_DATA: + audqcelp_send_data(audio, 1); + break; + + case AUDPLAY_MSG_BUFFER_UPDATE: + audqcelp_update_pcm_buf_entry(audio, msg); + break; + + default: + pr_err("unexpected message from decoder \n"); + } +} + +static void audqcelp_dsp_event(void *private, unsigned id, uint16_t *msg) +{ + struct audio *audio = private; + + switch (id) { + case AUDPP_MSG_STATUS_MSG:{ + unsigned status = msg[1]; + + switch (status) { + case AUDPP_DEC_STATUS_SLEEP: + dprintk("decoder status: sleep \n"); + break; + + case AUDPP_DEC_STATUS_INIT: + dprintk("decoder status: init \n"); + audpp_cmd_cfg_routing_mode(audio); + break; + + case AUDPP_DEC_STATUS_CFG: + dprintk("decoder status: cfg \n"); + break; + case AUDPP_DEC_STATUS_PLAY: + dprintk("decoder status: play \n"); + if (audio->pcm_feedback) { + audqcelp_config_hostpcm(audio); + audqcelp_buffer_refresh(audio); + } + break; + default: + pr_err("unknown decoder status \n"); + } + break; + } + case AUDPP_MSG_CFG_MSG: + if (msg[0] == AUDPP_MSG_ENA_ENA) { + dprintk("audqcelp_dsp_event: CFG_MSG ENABLE\n"); + auddec_dsp_config(audio, 1); + audio->out_needed = 0; + audio->running = 1; + audpp_set_volume_and_pan(audio->dec_id, audio->volume, + 0); + audpp_avsync(audio->dec_id, 22050); + } else if (msg[0] == AUDPP_MSG_ENA_DIS) { + dprintk("audqcelp_dsp_event: CFG_MSG DISABLE\n"); + audpp_avsync(audio->dec_id, 0); + audio->running = 0; + } else { + pr_err("audqcelp_dsp_event: CFG_MSG %d?\n", msg[0]); + } + break; + case AUDPP_MSG_ROUTING_ACK: + dprintk("audqcelp_dsp_event: ROUTING_ACK mode=%d\n", msg[1]); + audpp_cmd_cfg_adec_params(audio); + break; + default: + pr_err("audqcelp_dsp_event: UNKNOWN (%d)\n", id); + } + +} + +struct msm_adsp_ops audplay_adsp_ops_qcelp = { + .event = audplay_dsp_event, +}; + +#define audplay_send_queue0(audio, cmd, len) \ + msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \ + cmd, len) + +static int auddec_dsp_config(struct audio *audio, int enable) +{ + audpp_cmd_cfg_dec_type cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE; + if (enable) + cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | + AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_QCELP; + else + cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V; + + return audpp_send_queue1(&cmd, sizeof(cmd)); +} + +static void audpp_cmd_cfg_adec_params(struct audio *audio) +{ + struct audpp_cmd_cfg_adec_params_v13k cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; + cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN; + cmd.common.dec_id = audio->dec_id; + cmd.common.input_sampling_frequency = 8000; + cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V; + + audpp_send_queue2(&cmd, sizeof(cmd)); +} + +static void audpp_cmd_cfg_routing_mode(struct audio *audio) +{ + struct audpp_cmd_routing_mode cmd; + dprintk("audpp_cmd_cfg_routing_mode()\n"); + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; + cmd.object_number = audio->dec_id; + if (audio->pcm_feedback) + cmd.routing_mode = ROUTING_MODE_FTRT; + else + cmd.routing_mode = ROUTING_MODE_RT; + audpp_send_queue1(&cmd, sizeof(cmd)); +} + +static int audplay_dsp_send_data_avail(struct audio *audio, + unsigned idx, unsigned len) +{ + audplay_cmd_bitstream_data_avail cmd; + + cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL; + cmd.decoder_id = audio->dec_id; + cmd.buf_ptr = audio->out[idx].addr; + cmd.buf_size = len / 2; + cmd.partition_number = 0; + return audplay_send_queue0(audio, &cmd, sizeof(cmd)); +} + +static void audqcelp_buffer_refresh(struct audio *audio) +{ + struct audplay_cmd_buffer_refresh refresh_cmd; + + refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; + refresh_cmd.num_buffers = 1; + refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; + refresh_cmd.buf0_length = audio->in[audio->fill_next].size; + refresh_cmd.buf_read_count = 0; + dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n", + refresh_cmd.buf0_address, refresh_cmd.buf0_length); + + (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); +} + +static void audqcelp_config_hostpcm(struct audio *audio) +{ + struct audplay_cmd_hpcm_buf_cfg cfg_cmd; + + dprintk("audqcelp_config_hostpcm()\n"); + cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; + cfg_cmd.max_buffers = audio->pcm_buf_count; + cfg_cmd.byte_swap = 0; + cfg_cmd.hostpcm_config = (0x8000) | (0x4000); + cfg_cmd.feedback_frequency = 1; + cfg_cmd.partition_number = 0; + + (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); +} + +static void audqcelp_send_data(struct audio *audio, unsigned needed) +{ + struct buffer *frame; + unsigned long flags; + + spin_lock_irqsave(&audio->dsp_lock, flags); + if (!audio->running) + goto done; + + if (needed) { + /* We were called from the callback because the DSP + * requested more data. Note that the DSP does want + * more data, and if a buffer was in-flight, mark it + * as available (since the DSP must now be done with + * it). + */ + audio->out_needed = 1; + frame = audio->out + audio->out_tail; + if (frame->used == 0xffffffff) { + dprintk("frame %d free\n", audio->out_tail); + frame->used = 0; + audio->out_tail ^= 1; + wake_up(&audio->write_wait); + } + } + + if (audio->out_needed) { + /* If the DSP currently wants data and we have a + * buffer available, we will send it and reset + * the needed flag. We'll mark the buffer as in-flight + * so that it won't be recycled until the next buffer + * is requested + */ + + frame = audio->out + audio->out_tail; + if (frame->used) { + BUG_ON(frame->used == 0xffffffff); + dprintk("frame %d busy\n", audio->out_tail); + audplay_dsp_send_data_avail(audio, audio->out_tail, + frame->used); + frame->used = 0xffffffff; + audio->out_needed = 0; + } + } + done: + spin_unlock_irqrestore(&audio->dsp_lock, flags); +} + +/* ------------------- device --------------------- */ + +static void audqcelp_flush(struct audio *audio) +{ + audio->out[0].used = 0; + audio->out[1].used = 0; + audio->out_head = 0; + audio->out_tail = 0; + audio->stopped = 0; +} + +static void audqcelp_flush_pcm_buf(struct audio *audio) +{ + uint8_t index; + + for (index = 0; index < PCM_BUF_MAX_COUNT; index++) + audio->in[index].used = 0; + + audio->read_next = 0; + audio->fill_next = 0; +} + +static long audqcelp_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct audio *audio = file->private_data; + int rc = 0; + + dprintk("audqcelp_ioctl() cmd = %d\n", cmd); + + if (cmd == AUDIO_GET_STATS) { + struct msm_audio_stats stats; + stats.byte_count = audpp_avsync_byte_count(audio->dec_id); + stats.sample_count = audpp_avsync_sample_count(audio->dec_id); + if (copy_to_user((void *)arg, &stats, sizeof(stats))) + return -EFAULT; + return 0; + } + if (cmd == AUDIO_SET_VOLUME) { + unsigned long flags; + spin_lock_irqsave(&audio->dsp_lock, flags); + audio->volume = arg; + if (audio->running) + audpp_set_volume_and_pan(audio->dec_id, arg, 0); + spin_unlock_irqrestore(&audio->dsp_lock, flags); + return 0; + } + mutex_lock(&audio->lock); + switch (cmd) { + case AUDIO_START: + rc = audqcelp_enable(audio); + break; + case AUDIO_STOP: + rc = audqcelp_disable(audio); + audio->stopped = 1; + break; + case AUDIO_FLUSH: + if (audio->stopped) { + /* Make sure we're stopped and we wake any threads + * that might be blocked holding the write_lock. + * While audio->stopped write threads will always + * exit immediately. + */ + wake_up(&audio->write_wait); + mutex_lock(&audio->write_lock); + audqcelp_flush(audio); + mutex_unlock(&audio->write_lock); + wake_up(&audio->read_wait); + mutex_lock(&audio->read_lock); + audqcelp_flush_pcm_buf(audio); + mutex_unlock(&audio->read_lock); + break; + } + break; + case AUDIO_SET_CONFIG: + dprintk("AUDIO_SET_CONFIG not applicable \n"); + break; + case AUDIO_GET_CONFIG:{ + struct msm_audio_config config; + config.buffer_size = BUFSZ; + config.buffer_count = BUF_COUNT; + config.sample_rate = 8000; + config.channel_count = 1; + config.unused[0] = 0; + config.unused[1] = 0; + config.unused[2] = 0; + config.unused[3] = 0; + if (copy_to_user((void *)arg, &config, + sizeof(config))) + rc = -EFAULT; + else + rc = 0; + + break; + } + case AUDIO_GET_PCM_CONFIG:{ + struct msm_audio_pcm_config config; + + config.pcm_feedback = 0; + config.buffer_count = PCM_BUF_MAX_COUNT; + config.buffer_size = PCM_BUFSZ_MIN; + if (copy_to_user((void *)arg, &config, + sizeof(config))) + rc = -EFAULT; + else + rc = 0; + break; + } + case AUDIO_SET_PCM_CONFIG:{ + struct msm_audio_pcm_config config; + + if (copy_from_user(&config, (void *)arg, + sizeof(config))) { + rc = -EFAULT; + break; + } + if ((config.buffer_count > PCM_BUF_MAX_COUNT) || + (config.buffer_count == 1)) + config.buffer_count = PCM_BUF_MAX_COUNT; + + if (config.buffer_size < PCM_BUFSZ_MIN) + config.buffer_size = PCM_BUFSZ_MIN; + + /* Check if pcm feedback is required */ + if ((config.pcm_feedback) && (!audio->read_data)) { + dprintk( + "audqcelp_ioctl: allocate PCM buf %d\n", + config.buffer_count * config.buffer_size); + audio->read_data = dma_alloc_coherent(NULL, + config.buffer_size * config.buffer_count, + &audio->read_phys, GFP_KERNEL); + if (!audio->read_data) { + pr_err( + "audqcelp_ioctl: no mem for pcm buf\n" + ); + rc = -ENOMEM; + } else { + uint8_t index; + uint32_t offset = 0; + + audio->pcm_feedback = 1; + audio->buf_refresh = 0; + audio->pcm_buf_count = + config.buffer_count; + audio->read_next = 0; + audio->fill_next = 0; + + for (index = 0; + index < config.buffer_count; index++) { + audio->in[index].data = + audio->read_data + offset; + audio->in[index].addr = + audio->read_phys + offset; + audio->in[index].size = + config.buffer_size; + audio->in[index].used = 0; + offset += config.buffer_size; + } + rc = 0; + } + } else { + rc = 0; + } + break; + } + case AUDIO_PAUSE: + dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg); + rc = audpp_pause(audio->dec_id, (int) arg); + break; + default: + rc = -EINVAL; + } + mutex_unlock(&audio->lock); + return rc; +} + +static ssize_t audqcelp_read(struct file *file, char __user *buf, size_t count, + loff_t *pos) +{ + struct audio *audio = file->private_data; + const char __user *start = buf; + int rc = 0; + + if (!audio->pcm_feedback) + return 0; /* PCM feedback is not enabled. Nothing to read */ + + mutex_lock(&audio->read_lock); + dprintk("audqcelp_read() %d \n", count); + while (count > 0) { + rc = wait_event_interruptible(audio->read_wait, + (audio->in[audio->read_next].used > 0) || + (audio->stopped)); + if (rc < 0) + break; + + if (audio->stopped) { + rc = -EBUSY; + break; + } + + if (count < audio->in[audio->read_next].used) { + /* Read must happen in frame boundary. Since driver does + not know frame size, read count must be greater or equal + to size of PCM samples */ + dprintk("audqcelp_read:read stop - partial frame\n"); + break; + } else { + dprintk("audqcelp_read: read from in[%d]\n", + audio->read_next); + if (copy_to_user(buf, + audio->in[audio->read_next].data, + audio->in[audio->read_next].used)) { + pr_err("audqcelp_read: invalid addr %x \n", + (unsigned int)buf); + rc = -EFAULT; + break; + } + count -= audio->in[audio->read_next].used; + buf += audio->in[audio->read_next].used; + audio->in[audio->read_next].used = 0; + if ((++audio->read_next) == audio->pcm_buf_count) + audio->read_next = 0; + } + } + + if (audio->buf_refresh) { + audio->buf_refresh = 0; + dprintk("audqcelp_read: kick start pcm feedback again\n"); + audqcelp_buffer_refresh(audio); + } + + mutex_unlock(&audio->read_lock); + + if (buf > start) + rc = buf - start; + + dprintk("audqcelp_read: read %d bytes\n", rc); + return rc; +} + +static ssize_t audqcelp_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + struct audio *audio = file->private_data; + const char __user *start = buf; + struct buffer *frame; + size_t xfer; + int rc = 0; + + if (count & 1) + return -EINVAL; + dprintk("audqcelp_write() \n"); + mutex_lock(&audio->write_lock); + while (count > 0) { + frame = audio->out + audio->out_head; + rc = wait_event_interruptible(audio->write_wait, + (frame->used == 0) + || (audio->stopped)); + dprintk("audqcelp_write() buffer available\n"); + if (rc < 0) + break; + if (audio->stopped) { + rc = -EBUSY; + break; + } + xfer = (count > frame->size) ? frame->size : count; + if (copy_from_user(frame->data, buf, xfer)) { + rc = -EFAULT; + break; + } + + frame->used = xfer; + audio->out_head ^= 1; + count -= xfer; + buf += xfer; + + audqcelp_send_data(audio, 0); + + } + mutex_unlock(&audio->write_lock); + if (buf > start) + return buf - start; + return rc; +} + +static int audqcelp_release(struct inode *inode, struct file *file) +{ + struct audio *audio = file->private_data; + + dprintk("audqcelp_release()\n"); + + mutex_lock(&audio->lock); + audqcelp_disable(audio); + audqcelp_flush(audio); + audqcelp_flush_pcm_buf(audio); + msm_adsp_put(audio->audplay); + audio->audplay = NULL; + audio->opened = 0; + if (audio->data) + dma_free_coherent(NULL, DMASZ, audio->data, audio->phys); + audio->data = NULL; + if (audio->read_data) { + dma_free_coherent(NULL, + audio->in[0].size * audio->pcm_buf_count, + audio->read_data, audio->read_phys); + audio->read_data = NULL; + } + audio->pcm_feedback = 0; + mutex_unlock(&audio->lock); + return 0; +} + +static int audqcelp_open(struct inode *inode, struct file *file) +{ + struct audio *audio = &the_qcelp_audio; + int rc; + + mutex_lock(&audio->lock); + + if (audio->opened) { + pr_err("audio: busy\n"); + rc = -EBUSY; + goto done; + } + + audio->data = dma_alloc_coherent(NULL, DMASZ, + &audio->phys, GFP_KERNEL); + if (!audio->data) { + pr_err("audio: could not allocate DMA buffers\n"); + rc = -ENOMEM; + goto done; + } + + rc = audmgr_open(&audio->audmgr); + if (rc) + goto err; + + rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay, + &audplay_adsp_ops_qcelp, audio); + if (rc) { + pr_err("audio: failed to get audplay0 dsp module\n"); + audmgr_close(&audio->audmgr); + goto err; + } + + audio->dec_id = 0; + + audio->out[0].data = audio->data + 0; + audio->out[0].addr = audio->phys + 0; + audio->out[0].size = BUFSZ; + + audio->out[1].data = audio->data + BUFSZ; + audio->out[1].addr = audio->phys + BUFSZ; + audio->out[1].size = BUFSZ; + + audio->volume = 0x2000; /* Q13 1.0 */ + + audqcelp_flush(audio); + + file->private_data = audio; + audio->opened = 1; + rc = 0; +done: + mutex_unlock(&audio->lock); + return rc; +err: + dma_free_coherent(NULL, DMASZ, audio->data, audio->phys); + mutex_unlock(&audio->lock); + return rc; +} + +static struct file_operations audio_qcelp_fops = { + .owner = THIS_MODULE, + .open = audqcelp_open, + .release = audqcelp_release, + .read = audqcelp_read, + .write = audqcelp_write, + .unlocked_ioctl = audqcelp_ioctl, + .llseek = noop_llseek, +}; + +struct miscdevice audio_qcelp_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_qcelp", + .fops = &audio_qcelp_fops, +}; + +static int __init audqcelp_init(void) +{ + mutex_init(&the_qcelp_audio.lock); + mutex_init(&the_qcelp_audio.write_lock); + mutex_init(&the_qcelp_audio.read_lock); + spin_lock_init(&the_qcelp_audio.dsp_lock); + init_waitqueue_head(&the_qcelp_audio.write_wait); + init_waitqueue_head(&the_qcelp_audio.read_wait); + the_qcelp_audio.read_data = NULL; + return misc_register(&audio_qcelp_misc); +} + +static void __exit audqcelp_exit(void) +{ + misc_deregister(&audio_qcelp_misc); +} + +module_init(audqcelp_init); +module_exit(audqcelp_exit); + +MODULE_DESCRIPTION("MSM QCELP 13K driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("QUALCOMM"); diff --git a/trunk/drivers/staging/dream/qdsp5/audmgr.c b/trunk/drivers/staging/dream/qdsp5/audmgr.c new file mode 100644 index 000000000000..427ae6c0bea8 --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/audmgr.c @@ -0,0 +1,314 @@ +/* arch/arm/mach-msm/qdsp5/audmgr.c + * + * interface to "audmgr" service on the baseband cpu + * + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "audmgr.h" + +#define STATE_CLOSED 0 +#define STATE_DISABLED 1 +#define STATE_ENABLING 2 +#define STATE_ENABLED 3 +#define STATE_DISABLING 4 +#define STATE_ERROR 5 + +static void rpc_ack(struct msm_rpc_endpoint *ept, uint32_t xid) +{ + uint32_t rep[6]; + + rep[0] = cpu_to_be32(xid); + rep[1] = cpu_to_be32(1); + rep[2] = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED); + rep[3] = cpu_to_be32(RPC_ACCEPTSTAT_SUCCESS); + rep[4] = 0; + rep[5] = 0; + + msm_rpc_write(ept, rep, sizeof(rep)); +} + +static void process_audmgr_callback(struct audmgr *am, + struct rpc_audmgr_cb_func_ptr *args, + int len) +{ + if (len < (sizeof(uint32_t) * 3)) + return; + if (be32_to_cpu(args->set_to_one) != 1) + return; + + switch (be32_to_cpu(args->status)) { + case RPC_AUDMGR_STATUS_READY: + if (len < sizeof(uint32_t) * 4) + break; + am->handle = be32_to_cpu(args->u.handle); + pr_info("audmgr: rpc READY handle=0x%08x\n", am->handle); + break; + case RPC_AUDMGR_STATUS_CODEC_CONFIG: { + uint32_t volume; + if (len < sizeof(uint32_t) * 4) + break; + volume = be32_to_cpu(args->u.volume); + pr_info("audmgr: rpc CODEC_CONFIG volume=0x%08x\n", volume); + am->state = STATE_ENABLED; + wake_up(&am->wait); + break; + } + case RPC_AUDMGR_STATUS_PENDING: + pr_err("audmgr: PENDING?\n"); + break; + case RPC_AUDMGR_STATUS_SUSPEND: + pr_err("audmgr: SUSPEND?\n"); + break; + case RPC_AUDMGR_STATUS_FAILURE: + pr_err("audmgr: FAILURE\n"); + break; + case RPC_AUDMGR_STATUS_VOLUME_CHANGE: + pr_err("audmgr: VOLUME_CHANGE?\n"); + break; + case RPC_AUDMGR_STATUS_DISABLED: + pr_err("audmgr: DISABLED\n"); + am->state = STATE_DISABLED; + wake_up(&am->wait); + break; + case RPC_AUDMGR_STATUS_ERROR: + pr_err("audmgr: ERROR?\n"); + am->state = STATE_ERROR; + wake_up(&am->wait); + break; + default: + break; + } +} + +static void process_rpc_request(uint32_t proc, uint32_t xid, + void *data, int len, void *private) +{ + struct audmgr *am = private; + uint32_t *x = data; + + if (0) { + int n = len / 4; + pr_info("rpc_call proc %d:", proc); + while (n--) + printk(" %08x", be32_to_cpu(*x++)); + printk("\n"); + } + + if (proc == AUDMGR_CB_FUNC_PTR) + process_audmgr_callback(am, data, len); + else + pr_err("audmgr: unknown rpc proc %d\n", proc); + rpc_ack(am->ept, xid); +} + +#define RPC_TYPE_REQUEST 0 +#define RPC_TYPE_REPLY 1 + +#define RPC_VERSION 2 + +#define RPC_COMMON_HDR_SZ (sizeof(uint32_t) * 2) +#define RPC_REQUEST_HDR_SZ (sizeof(struct rpc_request_hdr)) +#define RPC_REPLY_HDR_SZ (sizeof(uint32_t) * 3) +#define RPC_REPLY_SZ (sizeof(uint32_t) * 6) + +static int audmgr_rpc_thread(void *data) +{ + struct audmgr *am = data; + struct rpc_request_hdr *hdr = NULL; + uint32_t type; + int len; + + pr_info("audmgr_rpc_thread() start\n"); + + while (!kthread_should_stop()) { + if (hdr) { + kfree(hdr); + hdr = NULL; + } + len = msm_rpc_read(am->ept, (void **) &hdr, -1, -1); + if (len < 0) { + pr_err("audmgr: rpc read failed (%d)\n", len); + break; + } + if (len < RPC_COMMON_HDR_SZ) + continue; + + type = be32_to_cpu(hdr->type); + if (type == RPC_TYPE_REPLY) { + struct rpc_reply_hdr *rep = (void *) hdr; + uint32_t status; + if (len < RPC_REPLY_HDR_SZ) + continue; + status = be32_to_cpu(rep->reply_stat); + if (status == RPCMSG_REPLYSTAT_ACCEPTED) { + status = be32_to_cpu(rep->data.acc_hdr.accept_stat); + pr_info("audmgr: rpc_reply status %d\n", status); + } else { + pr_info("audmgr: rpc_reply denied!\n"); + } + /* process reply */ + continue; + } + + if (len < RPC_REQUEST_HDR_SZ) + continue; + + process_rpc_request(be32_to_cpu(hdr->procedure), + be32_to_cpu(hdr->xid), + (void *) (hdr + 1), + len - sizeof(*hdr), + data); + } + pr_info("audmgr_rpc_thread() exit\n"); + if (hdr) { + kfree(hdr); + hdr = NULL; + } + am->task = NULL; + wake_up(&am->wait); + return 0; +} + +struct audmgr_enable_msg { + struct rpc_request_hdr hdr; + struct rpc_audmgr_enable_client_args args; +}; + +struct audmgr_disable_msg { + struct rpc_request_hdr hdr; + uint32_t handle; +}; + +int audmgr_open(struct audmgr *am) +{ + int rc; + + if (am->state != STATE_CLOSED) + return 0; + + am->ept = msm_rpc_connect(AUDMGR_PROG, + AUDMGR_VERS, + MSM_RPC_UNINTERRUPTIBLE); + + init_waitqueue_head(&am->wait); + + if (IS_ERR(am->ept)) { + rc = PTR_ERR(am->ept); + am->ept = NULL; + pr_err("audmgr: failed to connect to audmgr svc\n"); + return rc; + } + + am->task = kthread_run(audmgr_rpc_thread, am, "audmgr_rpc"); + if (IS_ERR(am->task)) { + rc = PTR_ERR(am->task); + am->task = NULL; + msm_rpc_close(am->ept); + am->ept = NULL; + return rc; + } + + am->state = STATE_DISABLED; + return 0; +} +EXPORT_SYMBOL(audmgr_open); + +int audmgr_close(struct audmgr *am) +{ + return -EBUSY; +} +EXPORT_SYMBOL(audmgr_close); + +int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg) +{ + struct audmgr_enable_msg msg; + int rc; + + if (am->state == STATE_ENABLED) + return 0; + + if (am->state == STATE_DISABLING) + pr_err("audmgr: state is DISABLING in enable?\n"); + am->state = STATE_ENABLING; + + msg.args.set_to_one = cpu_to_be32(1); + msg.args.tx_sample_rate = cpu_to_be32(cfg->tx_rate); + msg.args.rx_sample_rate = cpu_to_be32(cfg->rx_rate); + msg.args.def_method = cpu_to_be32(cfg->def_method); + msg.args.codec_type = cpu_to_be32(cfg->codec); + msg.args.snd_method = cpu_to_be32(cfg->snd_method); + msg.args.cb_func = cpu_to_be32(0x11111111); + msg.args.client_data = cpu_to_be32(0x11223344); + + msm_rpc_setup_req(&msg.hdr, AUDMGR_PROG, msm_rpc_get_vers(am->ept), + AUDMGR_ENABLE_CLIENT); + + rc = msm_rpc_write(am->ept, &msg, sizeof(msg)); + if (rc < 0) + return rc; + + rc = wait_event_timeout(am->wait, am->state != STATE_ENABLING, 15 * HZ); + if (rc == 0) { + pr_err("audmgr_enable: ARM9 did not reply to RPC am->state = %d\n", am->state); + BUG(); + } + if (am->state == STATE_ENABLED) + return 0; + + pr_err("audmgr: unexpected state %d while enabling?!\n", am->state); + return -ENODEV; +} +EXPORT_SYMBOL(audmgr_enable); + +int audmgr_disable(struct audmgr *am) +{ + struct audmgr_disable_msg msg; + int rc; + + if (am->state == STATE_DISABLED) + return 0; + + msm_rpc_setup_req(&msg.hdr, AUDMGR_PROG, msm_rpc_get_vers(am->ept), + AUDMGR_DISABLE_CLIENT); + msg.handle = cpu_to_be32(am->handle); + + am->state = STATE_DISABLING; + + rc = msm_rpc_write(am->ept, &msg, sizeof(msg)); + if (rc < 0) + return rc; + + rc = wait_event_timeout(am->wait, am->state != STATE_DISABLING, 15 * HZ); + if (rc == 0) { + pr_err("audmgr_disable: ARM9 did not reply to RPC am->state = %d\n", am->state); + BUG(); + } + + if (am->state == STATE_DISABLED) + return 0; + + pr_err("audmgr: unexpected state %d while disabling?!\n", am->state); + return -ENODEV; +} +EXPORT_SYMBOL(audmgr_disable); diff --git a/trunk/drivers/staging/dream/qdsp5/audmgr.h b/trunk/drivers/staging/dream/qdsp5/audmgr.h new file mode 100644 index 000000000000..c07c36b3a0a3 --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/audmgr.h @@ -0,0 +1,215 @@ +/* arch/arm/mach-msm/qdsp5/audmgr.h + * + * Copyright 2008 (c) QUALCOMM Incorporated. + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _ARCH_ARM_MACH_MSM_AUDMGR_H +#define _ARCH_ARM_MACH_MSM_AUDMGR_H + +#if CONFIG_MSM_AMSS_VERSION==6350 +#include "audmgr_new.h" +#else + +enum rpc_aud_def_sample_rate_type { + RPC_AUD_DEF_SAMPLE_RATE_NONE, + RPC_AUD_DEF_SAMPLE_RATE_8000, + RPC_AUD_DEF_SAMPLE_RATE_11025, + RPC_AUD_DEF_SAMPLE_RATE_12000, + RPC_AUD_DEF_SAMPLE_RATE_16000, + RPC_AUD_DEF_SAMPLE_RATE_22050, + RPC_AUD_DEF_SAMPLE_RATE_24000, + RPC_AUD_DEF_SAMPLE_RATE_32000, + RPC_AUD_DEF_SAMPLE_RATE_44100, + RPC_AUD_DEF_SAMPLE_RATE_48000, + RPC_AUD_DEF_SAMPLE_RATE_MAX, +}; + +enum rpc_aud_def_method_type { + RPC_AUD_DEF_METHOD_NONE, + RPC_AUD_DEF_METHOD_KEY_BEEP, + RPC_AUD_DEF_METHOD_PLAYBACK, + RPC_AUD_DEF_METHOD_VOICE, + RPC_AUD_DEF_METHOD_RECORD, + RPC_AUD_DEF_METHOD_HOST_PCM, + RPC_AUD_DEF_METHOD_MIDI_OUT, + RPC_AUD_DEF_METHOD_RECORD_SBC, + RPC_AUD_DEF_METHOD_DTMF_RINGER, + RPC_AUD_DEF_METHOD_MAX, +}; + +enum rpc_aud_def_codec_type { + RPC_AUD_DEF_CODEC_NONE, + RPC_AUD_DEF_CODEC_DTMF, + RPC_AUD_DEF_CODEC_MIDI, + RPC_AUD_DEF_CODEC_MP3, + RPC_AUD_DEF_CODEC_PCM, + RPC_AUD_DEF_CODEC_AAC, + RPC_AUD_DEF_CODEC_WMA, + RPC_AUD_DEF_CODEC_RA, + RPC_AUD_DEF_CODEC_ADPCM, + RPC_AUD_DEF_CODEC_GAUDIO, + RPC_AUD_DEF_CODEC_VOC_EVRC, + RPC_AUD_DEF_CODEC_VOC_13K, + RPC_AUD_DEF_CODEC_VOC_4GV_NB, + RPC_AUD_DEF_CODEC_VOC_AMR, + RPC_AUD_DEF_CODEC_VOC_EFR, + RPC_AUD_DEF_CODEC_VOC_FR, + RPC_AUD_DEF_CODEC_VOC_HR, + RPC_AUD_DEF_CODEC_VOC, + RPC_AUD_DEF_CODEC_SBC, + RPC_AUD_DEF_CODEC_VOC_PCM, + RPC_AUD_DEF_CODEC_AMR_WB, + RPC_AUD_DEF_CODEC_AMR_WB_PLUS, + RPC_AUD_DEF_CODEC_MAX, +}; + +enum rpc_snd_method_type { + RPC_SND_METHOD_VOICE = 0, + RPC_SND_METHOD_KEY_BEEP, + RPC_SND_METHOD_MESSAGE, + RPC_SND_METHOD_RING, + RPC_SND_METHOD_MIDI, + RPC_SND_METHOD_AUX, + RPC_SND_METHOD_MAX, +}; + +enum rpc_voc_codec_type { + RPC_VOC_CODEC_DEFAULT, + RPC_VOC_CODEC_ON_CHIP_0 = RPC_VOC_CODEC_DEFAULT, + RPC_VOC_CODEC_ON_CHIP_1, + RPC_VOC_CODEC_STEREO_HEADSET, + RPC_VOC_CODEC_ON_CHIP_AUX, + RPC_VOC_CODEC_BT_OFF_BOARD, + RPC_VOC_CODEC_BT_A2DP, + RPC_VOC_CODEC_OFF_BOARD, + RPC_VOC_CODEC_SDAC, + RPC_VOC_CODEC_RX_EXT_SDAC_TX_INTERNAL, + RPC_VOC_CODEC_IN_STEREO_SADC_OUT_MONO_HANDSET, + RPC_VOC_CODEC_IN_STEREO_SADC_OUT_STEREO_HEADSET, + RPC_VOC_CODEC_TX_INT_SADC_RX_EXT_AUXPCM, + RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_MONO_HANDSET, + RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_STEREO_HEADSET, + RPC_VOC_CODEC_TTY_ON_CHIP_1, + RPC_VOC_CODEC_TTY_OFF_BOARD, + RPC_VOC_CODEC_TTY_VCO, + RPC_VOC_CODEC_TTY_HCO, + RPC_VOC_CODEC_ON_CHIP_0_DUAL_MIC, + RPC_VOC_CODEC_MAX, + RPC_VOC_CODEC_NONE, +}; + +enum rpc_audmgr_status_type { + RPC_AUDMGR_STATUS_READY, + RPC_AUDMGR_STATUS_CODEC_CONFIG, + RPC_AUDMGR_STATUS_PENDING, + RPC_AUDMGR_STATUS_SUSPEND, + RPC_AUDMGR_STATUS_FAILURE, + RPC_AUDMGR_STATUS_VOLUME_CHANGE, + RPC_AUDMGR_STATUS_DISABLED, + RPC_AUDMGR_STATUS_ERROR, +}; + +struct rpc_audmgr_enable_client_args { + uint32_t set_to_one; + uint32_t tx_sample_rate; + uint32_t rx_sample_rate; + uint32_t def_method; + uint32_t codec_type; + uint32_t snd_method; + + uint32_t cb_func; + uint32_t client_data; +}; + +#define AUDMGR_ENABLE_CLIENT 2 +#define AUDMGR_DISABLE_CLIENT 3 +#define AUDMGR_SUSPEND_EVENT_RSP 4 +#define AUDMGR_REGISTER_OPERATION_LISTENER 5 +#define AUDMGR_UNREGISTER_OPERATION_LISTENER 6 +#define AUDMGR_REGISTER_CODEC_LISTENER 7 +#define AUDMGR_GET_RX_SAMPLE_RATE 8 +#define AUDMGR_GET_TX_SAMPLE_RATE 9 +#define AUDMGR_SET_DEVICE_MODE 10 + +#if CONFIG_MSM_AMSS_VERSION < 6220 +#define AUDMGR_PROG_VERS "rs30000013:46255756" +#define AUDMGR_PROG 0x30000013 +#define AUDMGR_VERS 0x46255756 +#else +#define AUDMGR_PROG_VERS "rs30000013:e94e8f0c" +#define AUDMGR_PROG 0x30000013 +#define AUDMGR_VERS 0xe94e8f0c +#endif + +struct rpc_audmgr_cb_func_ptr { + uint32_t cb_id; + uint32_t set_to_one; + uint32_t status; + union { + uint32_t handle; + uint32_t volume; + + } u; +}; + +#define AUDMGR_CB_FUNC_PTR 1 +#define AUDMGR_OPR_LSTNR_CB_FUNC_PTR 2 +#define AUDMGR_CODEC_LSTR_FUNC_PTR 3 + +#if CONFIG_MSM_AMSS_VERSION < 6220 +#define AUDMGR_CB_PROG 0x31000013 +#define AUDMGR_CB_VERS 0x5fa922a9 +#else +#define AUDMGR_CB_PROG 0x31000013 +#define AUDMGR_CB_VERS 0x21570ba7 +#endif + +struct audmgr { + wait_queue_head_t wait; + uint32_t handle; + struct msm_rpc_endpoint *ept; + struct task_struct *task; + int state; +}; + +struct audmgr_config { + uint32_t tx_rate; + uint32_t rx_rate; + uint32_t def_method; + uint32_t codec; + uint32_t snd_method; +}; + +int audmgr_open(struct audmgr *am); +int audmgr_close(struct audmgr *am); +int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg); +int audmgr_disable(struct audmgr *am); + +typedef void (*audpp_event_func)(void *private, unsigned id, uint16_t *msg); + +int audpp_enable(int id, audpp_event_func func, void *private); +void audpp_disable(int id, void *private); + +int audpp_send_queue1(void *cmd, unsigned len); +int audpp_send_queue2(void *cmd, unsigned len); +int audpp_send_queue3(void *cmd, unsigned len); + +int audpp_pause(unsigned id, int pause); +int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan); +void audpp_avsync(int id, unsigned rate); +unsigned audpp_avsync_sample_count(int id); +unsigned audpp_avsync_byte_count(int id); + +#endif +#endif diff --git a/trunk/drivers/staging/dream/qdsp5/audmgr_new.h b/trunk/drivers/staging/dream/qdsp5/audmgr_new.h new file mode 100644 index 000000000000..49670fe48b9e --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/audmgr_new.h @@ -0,0 +1,213 @@ +/* arch/arm/mach-msm/qdsp5/audmgr.h + * + * Copyright 2008 (c) QUALCOMM Incorporated. + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _ARCH_ARM_MACH_MSM_AUDMGR_NEW_H +#define _ARCH_ARM_MACH_MSM_AUDMGR_NEW_H + +enum rpc_aud_def_sample_rate_type { + RPC_AUD_DEF_SAMPLE_RATE_NONE, + RPC_AUD_DEF_SAMPLE_RATE_8000, + RPC_AUD_DEF_SAMPLE_RATE_11025, + RPC_AUD_DEF_SAMPLE_RATE_12000, + RPC_AUD_DEF_SAMPLE_RATE_16000, + RPC_AUD_DEF_SAMPLE_RATE_22050, + RPC_AUD_DEF_SAMPLE_RATE_24000, + RPC_AUD_DEF_SAMPLE_RATE_32000, + RPC_AUD_DEF_SAMPLE_RATE_44100, + RPC_AUD_DEF_SAMPLE_RATE_48000, + RPC_AUD_DEF_SAMPLE_RATE_MAX, +}; + +enum rpc_aud_def_method_type { + RPC_AUD_DEF_METHOD_NONE, + RPC_AUD_DEF_METHOD_KEY_BEEP, + RPC_AUD_DEF_METHOD_PLAYBACK, + RPC_AUD_DEF_METHOD_VOICE, + RPC_AUD_DEF_METHOD_RECORD, + RPC_AUD_DEF_METHOD_HOST_PCM, + RPC_AUD_DEF_METHOD_MIDI_OUT, + RPC_AUD_DEF_METHOD_RECORD_SBC, + RPC_AUD_DEF_METHOD_DTMF_RINGER, + RPC_AUD_DEF_METHOD_MAX, +}; + +enum rpc_aud_def_codec_type { + RPC_AUD_DEF_CODEC_NONE, + RPC_AUD_DEF_CODEC_DTMF, + RPC_AUD_DEF_CODEC_MIDI, + RPC_AUD_DEF_CODEC_MP3, + RPC_AUD_DEF_CODEC_PCM, + RPC_AUD_DEF_CODEC_AAC, + RPC_AUD_DEF_CODEC_WMA, + RPC_AUD_DEF_CODEC_RA, + RPC_AUD_DEF_CODEC_ADPCM, + RPC_AUD_DEF_CODEC_GAUDIO, + RPC_AUD_DEF_CODEC_VOC_EVRC, + RPC_AUD_DEF_CODEC_VOC_13K, + RPC_AUD_DEF_CODEC_VOC_4GV_NB, + RPC_AUD_DEF_CODEC_VOC_AMR, + RPC_AUD_DEF_CODEC_VOC_EFR, + RPC_AUD_DEF_CODEC_VOC_FR, + RPC_AUD_DEF_CODEC_VOC_HR, + RPC_AUD_DEF_CODEC_VOC_CDMA, + RPC_AUD_DEF_CODEC_VOC_CDMA_WB, + RPC_AUD_DEF_CODEC_VOC_UMTS, + RPC_AUD_DEF_CODEC_VOC_UMTS_WB, + RPC_AUD_DEF_CODEC_SBC, + RPC_AUD_DEF_CODEC_VOC_PCM, + RPC_AUD_DEF_CODEC_AMR_WB, + RPC_AUD_DEF_CODEC_AMR_WB_PLUS, + RPC_AUD_DEF_CODEC_AAC_BSAC, + RPC_AUD_DEF_CODEC_MAX, + RPC_AUD_DEF_CODEC_AMR_NB, + RPC_AUD_DEF_CODEC_13K, + RPC_AUD_DEF_CODEC_EVRC, + RPC_AUD_DEF_CODEC_MAX_002, +}; + +enum rpc_snd_method_type { + RPC_SND_METHOD_VOICE = 0, + RPC_SND_METHOD_KEY_BEEP, + RPC_SND_METHOD_MESSAGE, + RPC_SND_METHOD_RING, + RPC_SND_METHOD_MIDI, + RPC_SND_METHOD_AUX, + RPC_SND_METHOD_MAX, +}; + +enum rpc_voc_codec_type { + RPC_VOC_CODEC_DEFAULT, + RPC_VOC_CODEC_ON_CHIP_0 = RPC_VOC_CODEC_DEFAULT, + RPC_VOC_CODEC_ON_CHIP_1, + RPC_VOC_CODEC_STEREO_HEADSET, + RPC_VOC_CODEC_ON_CHIP_AUX, + RPC_VOC_CODEC_BT_OFF_BOARD, + RPC_VOC_CODEC_BT_A2DP, + RPC_VOC_CODEC_OFF_BOARD, + RPC_VOC_CODEC_SDAC, + RPC_VOC_CODEC_RX_EXT_SDAC_TX_INTERNAL, + RPC_VOC_CODEC_IN_STEREO_SADC_OUT_MONO_HANDSET, + RPC_VOC_CODEC_IN_STEREO_SADC_OUT_STEREO_HEADSET, + RPC_VOC_CODEC_TX_INT_SADC_RX_EXT_AUXPCM, + RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_MONO_HANDSET, + RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_STEREO_HEADSET, + RPC_VOC_CODEC_TTY_ON_CHIP_1, + RPC_VOC_CODEC_TTY_OFF_BOARD, + RPC_VOC_CODEC_TTY_VCO, + RPC_VOC_CODEC_TTY_HCO, + RPC_VOC_CODEC_ON_CHIP_0_DUAL_MIC, + RPC_VOC_CODEC_MAX, + RPC_VOC_CODEC_NONE, +}; + +enum rpc_audmgr_status_type { + RPC_AUDMGR_STATUS_READY, + RPC_AUDMGR_STATUS_CODEC_CONFIG, + RPC_AUDMGR_STATUS_PENDING, + RPC_AUDMGR_STATUS_SUSPEND, + RPC_AUDMGR_STATUS_FAILURE, + RPC_AUDMGR_STATUS_VOLUME_CHANGE, + RPC_AUDMGR_STATUS_DISABLED, + RPC_AUDMGR_STATUS_ERROR, +}; + +struct rpc_audmgr_enable_client_args { + uint32_t set_to_one; + uint32_t tx_sample_rate; + uint32_t rx_sample_rate; + uint32_t def_method; + uint32_t codec_type; + uint32_t snd_method; + + uint32_t cb_func; + uint32_t client_data; +}; + +#define AUDMGR_ENABLE_CLIENT 2 +#define AUDMGR_DISABLE_CLIENT 3 +#define AUDMGR_SUSPEND_EVENT_RSP 4 +#define AUDMGR_REGISTER_OPERATION_LISTENER 5 +#define AUDMGR_UNREGISTER_OPERATION_LISTENER 6 +#define AUDMGR_REGISTER_CODEC_LISTENER 7 +#define AUDMGR_GET_RX_SAMPLE_RATE 8 +#define AUDMGR_GET_TX_SAMPLE_RATE 9 +#define AUDMGR_SET_DEVICE_MODE 10 + +#define AUDMGR_PROG 0x30000013 +#define AUDMGR_VERS MSM_RPC_VERS(1,0) + +struct rpc_audmgr_cb_func_ptr { + uint32_t cb_id; + uint32_t status; /* Audmgr status */ + uint32_t set_to_one; /* Pointer status (1 = valid, 0 = invalid) */ + uint32_t disc; + /* disc = AUDMGR_STATUS_READY => data=handle + disc = AUDMGR_STATUS_CODEC_CONFIG => data = handle + disc = AUDMGR_STATUS_DISABLED => data =status_disabled + disc = AUDMGR_STATUS_VOLUME_CHANGE => data = volume-change */ + union { + uint32_t handle; + uint32_t volume; + uint32_t status_disabled; + uint32_t volume_change; + } u; +}; + +#define AUDMGR_CB_FUNC_PTR 1 +#define AUDMGR_OPR_LSTNR_CB_FUNC_PTR 2 +#define AUDMGR_CODEC_LSTR_FUNC_PTR 3 + +#define AUDMGR_CB_PROG 0x31000013 +#define AUDMGR_CB_VERS 0xf8e3e2d9 + +struct audmgr { + wait_queue_head_t wait; + uint32_t handle; + struct msm_rpc_endpoint *ept; + struct task_struct *task; + int state; +}; + +struct audmgr_config { + uint32_t tx_rate; + uint32_t rx_rate; + uint32_t def_method; + uint32_t codec; + uint32_t snd_method; +}; + +int audmgr_open(struct audmgr *am); +int audmgr_close(struct audmgr *am); +int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg); +int audmgr_disable(struct audmgr *am); + +typedef void (*audpp_event_func)(void *private, unsigned id, uint16_t *msg); + +int audpp_enable(int id, audpp_event_func func, void *private); +void audpp_disable(int id, void *private); + +int audpp_send_queue1(void *cmd, unsigned len); +int audpp_send_queue2(void *cmd, unsigned len); +int audpp_send_queue3(void *cmd, unsigned len); + +int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan); +int audpp_pause(unsigned id, int pause); +int audpp_flush(unsigned id); +void audpp_avsync(int id, unsigned rate); +unsigned audpp_avsync_sample_count(int id); +unsigned audpp_avsync_byte_count(int id); + +#endif diff --git a/trunk/drivers/staging/dream/qdsp5/audpp.c b/trunk/drivers/staging/dream/qdsp5/audpp.c new file mode 100644 index 000000000000..d06556eda316 --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/audpp.c @@ -0,0 +1,429 @@ + +/* arch/arm/mach-msm/qdsp5/audpp.c + * + * common code to deal with the AUDPP dsp task (audio postproc) + * + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "audmgr.h" + +#include +#include + +/* for queue ids - should be relative to module number*/ +#include "adsp.h" + +#include "evlog.h" + + +enum { + EV_NULL, + EV_ENABLE, + EV_DISABLE, + EV_EVENT, + EV_DATA, +}; + +static const char *dsp_log_strings[] = { + "NULL", + "ENABLE", + "DISABLE", + "EVENT", + "DATA", +}; + +DECLARE_LOG(dsp_log, 64, dsp_log_strings); + +static int __init _dsp_log_init(void) +{ + return ev_log_init(&dsp_log); +} +module_init(_dsp_log_init); +#define LOG(id,arg) ev_log_write(&dsp_log, id, arg) + +static DEFINE_MUTEX(audpp_lock); + +#define CH_COUNT 5 +#define AUDPP_CLNT_MAX_COUNT 6 +#define AUDPP_AVSYNC_INFO_SIZE 7 + +struct audpp_state { + struct msm_adsp_module *mod; + audpp_event_func func[AUDPP_CLNT_MAX_COUNT]; + void *private[AUDPP_CLNT_MAX_COUNT]; + struct mutex *lock; + unsigned open_count; + unsigned enabled; + + /* which channels are actually enabled */ + unsigned avsync_mask; + + /* flags, 48 bits sample/bytes counter per channel */ + uint16_t avsync[CH_COUNT * AUDPP_CLNT_MAX_COUNT + 1]; +}; + +struct audpp_state the_audpp_state = { + .lock = &audpp_lock, +}; + +int audpp_send_queue1(void *cmd, unsigned len) +{ + return msm_adsp_write(the_audpp_state.mod, + QDSP_uPAudPPCmd1Queue, cmd, len); +} +EXPORT_SYMBOL(audpp_send_queue1); + +int audpp_send_queue2(void *cmd, unsigned len) +{ + return msm_adsp_write(the_audpp_state.mod, + QDSP_uPAudPPCmd2Queue, cmd, len); +} +EXPORT_SYMBOL(audpp_send_queue2); + +int audpp_send_queue3(void *cmd, unsigned len) +{ + return msm_adsp_write(the_audpp_state.mod, + QDSP_uPAudPPCmd3Queue, cmd, len); +} +EXPORT_SYMBOL(audpp_send_queue3); + +static int audpp_dsp_config(int enable) +{ + audpp_cmd_cfg cmd; + + cmd.cmd_id = AUDPP_CMD_CFG; + cmd.cfg = enable ? AUDPP_CMD_CFG_ENABLE : AUDPP_CMD_CFG_SLEEP; + + return audpp_send_queue1(&cmd, sizeof(cmd)); +} + +static void audpp_broadcast(struct audpp_state *audpp, unsigned id, + uint16_t *msg) +{ + unsigned n; + for (n = 0; n < AUDPP_CLNT_MAX_COUNT; n++) { + if (audpp->func[n]) + audpp->func[n] (audpp->private[n], id, msg); + } +} + +static void audpp_notify_clnt(struct audpp_state *audpp, unsigned clnt_id, + unsigned id, uint16_t *msg) +{ + if (clnt_id < AUDPP_CLNT_MAX_COUNT && audpp->func[clnt_id]) + audpp->func[clnt_id] (audpp->private[clnt_id], id, msg); +} + +static void audpp_dsp_event(void *data, unsigned id, size_t len, + void (*getevent)(void *ptr, size_t len)) +{ + struct audpp_state *audpp = data; + uint16_t msg[8]; + + if (id == AUDPP_MSG_AVSYNC_MSG) { + getevent(audpp->avsync, sizeof(audpp->avsync)); + + /* mask off any channels we're not watching to avoid + * cases where we might get one last update after + * disabling avsync and end up in an odd state when + * we next read... + */ + audpp->avsync[0] &= audpp->avsync_mask; + return; + } + + getevent(msg, sizeof(msg)); + + LOG(EV_EVENT, (id << 16) | msg[0]); + LOG(EV_DATA, (msg[1] << 16) | msg[2]); + + switch (id) { + case AUDPP_MSG_STATUS_MSG:{ + unsigned cid = msg[0]; + pr_info("audpp: status %d %d %d\n", cid, msg[1], + msg[2]); + if ((cid < 5) && audpp->func[cid]) + audpp->func[cid] (audpp->private[cid], id, msg); + break; + } + case AUDPP_MSG_HOST_PCM_INTF_MSG: + if (audpp->func[5]) + audpp->func[5] (audpp->private[5], id, msg); + break; + case AUDPP_MSG_PCMDMAMISSED: + pr_err("audpp: DMA missed obj=%x\n", msg[0]); + break; + case AUDPP_MSG_CFG_MSG: + if (msg[0] == AUDPP_MSG_ENA_ENA) { + pr_info("audpp: ENABLE\n"); + audpp->enabled = 1; + audpp_broadcast(audpp, id, msg); + } else if (msg[0] == AUDPP_MSG_ENA_DIS) { + pr_info("audpp: DISABLE\n"); + audpp->enabled = 0; + audpp_broadcast(audpp, id, msg); + } else { + pr_err("audpp: invalid config msg %d\n", msg[0]); + } + break; + case AUDPP_MSG_ROUTING_ACK: + audpp_broadcast(audpp, id, msg); + break; + case AUDPP_MSG_FLUSH_ACK: + audpp_notify_clnt(audpp, msg[0], id, msg); + break; + default: + pr_info("audpp: unhandled msg id %x\n", id); + } +} + +static struct msm_adsp_ops adsp_ops = { + .event = audpp_dsp_event, +}; + +static void audpp_fake_event(struct audpp_state *audpp, int id, + unsigned event, unsigned arg) +{ + uint16_t msg[1]; + msg[0] = arg; + audpp->func[id] (audpp->private[id], event, msg); +} + +int audpp_enable(int id, audpp_event_func func, void *private) +{ + struct audpp_state *audpp = &the_audpp_state; + int res = 0; + + if (id < -1 || id > 4) + return -EINVAL; + + if (id == -1) + id = 5; + + mutex_lock(audpp->lock); + if (audpp->func[id]) { + res = -EBUSY; + goto out; + } + + audpp->func[id] = func; + audpp->private[id] = private; + + LOG(EV_ENABLE, 1); + if (audpp->open_count++ == 0) { + pr_info("audpp: enable\n"); + res = msm_adsp_get("AUDPPTASK", &audpp->mod, &adsp_ops, audpp); + if (res < 0) { + pr_err("audpp: cannot open AUDPPTASK\n"); + audpp->open_count = 0; + audpp->func[id] = NULL; + audpp->private[id] = NULL; + goto out; + } + LOG(EV_ENABLE, 2); + msm_adsp_enable(audpp->mod); + audpp_dsp_config(1); + } else { + unsigned long flags; + local_irq_save(flags); + if (audpp->enabled) + audpp_fake_event(audpp, id, + AUDPP_MSG_CFG_MSG, AUDPP_MSG_ENA_ENA); + local_irq_restore(flags); + } + + res = 0; +out: + mutex_unlock(audpp->lock); + return res; +} +EXPORT_SYMBOL(audpp_enable); + +void audpp_disable(int id, void *private) +{ + struct audpp_state *audpp = &the_audpp_state; + unsigned long flags; + + if (id < -1 || id > 4) + return; + + if (id == -1) + id = 5; + + mutex_lock(audpp->lock); + LOG(EV_DISABLE, 1); + if (!audpp->func[id]) + goto out; + if (audpp->private[id] != private) + goto out; + + local_irq_save(flags); + audpp_fake_event(audpp, id, AUDPP_MSG_CFG_MSG, AUDPP_MSG_ENA_DIS); + audpp->func[id] = NULL; + audpp->private[id] = NULL; + local_irq_restore(flags); + + if (--audpp->open_count == 0) { + pr_info("audpp: disable\n"); + LOG(EV_DISABLE, 2); + audpp_dsp_config(0); + msm_adsp_disable(audpp->mod); + msm_adsp_put(audpp->mod); + audpp->mod = NULL; + } +out: + mutex_unlock(audpp->lock); +} +EXPORT_SYMBOL(audpp_disable); + +#define BAD_ID(id) ((id < 0) || (id >= CH_COUNT)) + +void audpp_avsync(int id, unsigned rate) +{ + unsigned long flags; + audpp_cmd_avsync cmd; + + if (BAD_ID(id)) + return; + + local_irq_save(flags); + if (rate) + the_audpp_state.avsync_mask |= (1 << id); + else + the_audpp_state.avsync_mask &= (~(1 << id)); + the_audpp_state.avsync[0] &= the_audpp_state.avsync_mask; + local_irq_restore(flags); + + cmd.cmd_id = AUDPP_CMD_AVSYNC; + cmd.object_number = id; + cmd.interrupt_interval_lsw = rate; + cmd.interrupt_interval_msw = rate >> 16; + audpp_send_queue1(&cmd, sizeof(cmd)); +} +EXPORT_SYMBOL(audpp_avsync); + +unsigned audpp_avsync_sample_count(int id) +{ + uint16_t *avsync = the_audpp_state.avsync; + unsigned val; + unsigned long flags; + unsigned mask; + + if (BAD_ID(id)) + return 0; + + mask = 1 << id; + id = id * AUDPP_AVSYNC_INFO_SIZE + 2; + local_irq_save(flags); + if (avsync[0] & mask) + val = (avsync[id] << 16) | avsync[id + 1]; + else + val = 0; + local_irq_restore(flags); + + return val; +} +EXPORT_SYMBOL(audpp_avsync_sample_count); + +unsigned audpp_avsync_byte_count(int id) +{ + uint16_t *avsync = the_audpp_state.avsync; + unsigned val; + unsigned long flags; + unsigned mask; + + if (BAD_ID(id)) + return 0; + + mask = 1 << id; + id = id * AUDPP_AVSYNC_INFO_SIZE + 5; + local_irq_save(flags); + if (avsync[0] & mask) + val = (avsync[id] << 16) | avsync[id + 1]; + else + val = 0; + local_irq_restore(flags); + + return val; +} +EXPORT_SYMBOL(audpp_avsync_byte_count); + +#define AUDPP_CMD_CFG_OBJ_UPDATE 0x8000 +#define AUDPP_CMD_VOLUME_PAN 0 + +int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan) +{ + /* cmd, obj_cfg[7], cmd_type, volume, pan */ + uint16_t cmd[11]; + + if (id > 6) + return -EINVAL; + + memset(cmd, 0, sizeof(cmd)); + cmd[0] = AUDPP_CMD_CFG_OBJECT_PARAMS; + cmd[1 + id] = AUDPP_CMD_CFG_OBJ_UPDATE; + cmd[8] = AUDPP_CMD_VOLUME_PAN; + cmd[9] = volume; + cmd[10] = pan; + + return audpp_send_queue3(cmd, sizeof(cmd)); +} +EXPORT_SYMBOL(audpp_set_volume_and_pan); + +int audpp_pause(unsigned id, int pause) +{ + /* pause 1 = pause 0 = resume */ + u16 pause_cmd[AUDPP_CMD_DEC_CTRL_LEN / sizeof(unsigned short)]; + + if (id >= CH_COUNT) + return -EINVAL; + + memset(pause_cmd, 0, sizeof(pause_cmd)); + + pause_cmd[0] = AUDPP_CMD_DEC_CTRL; + if (pause == 1) + pause_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_PAUSE_V; + else if (pause == 0) + pause_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_RESUME_V; + else + return -EINVAL; + + return audpp_send_queue1(pause_cmd, sizeof(pause_cmd)); +} +EXPORT_SYMBOL(audpp_pause); + +int audpp_flush(unsigned id) +{ + u16 flush_cmd[AUDPP_CMD_DEC_CTRL_LEN / sizeof(unsigned short)]; + + if (id >= CH_COUNT) + return -EINVAL; + + memset(flush_cmd, 0, sizeof(flush_cmd)); + + flush_cmd[0] = AUDPP_CMD_DEC_CTRL; + flush_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_FLUSH_V; + + return audpp_send_queue1(flush_cmd, sizeof(flush_cmd)); +} +EXPORT_SYMBOL(audpp_flush); diff --git a/trunk/drivers/staging/dream/qdsp5/evlog.h b/trunk/drivers/staging/dream/qdsp5/evlog.h new file mode 100644 index 000000000000..e5ab86b9dd7c --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/evlog.h @@ -0,0 +1,134 @@ +/* arch/arm/mach-msm/qdsp5/evlog.h + * + * simple event log debugging facility + * + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include + +#define EV_LOG_ENTRY_NAME(n) n##_entry + +#define DECLARE_LOG(_name, _size, _str) \ +static struct ev_entry EV_LOG_ENTRY_NAME(_name)[_size]; \ +static struct ev_log _name = { \ + .name = #_name, \ + .strings = _str, \ + .num_strings = ARRAY_SIZE(_str), \ + .entry = EV_LOG_ENTRY_NAME(_name), \ + .max = ARRAY_SIZE(EV_LOG_ENTRY_NAME(_name)), \ +} + +struct ev_entry { + ktime_t when; + uint32_t id; + uint32_t arg; +}; + +struct ev_log { + struct ev_entry *entry; + unsigned max; + unsigned next; + unsigned fault; + const char **strings; + unsigned num_strings; + const char *name; +}; + +static char ev_buf[4096]; + +static ssize_t ev_log_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct ev_log *log = file->private_data; + struct ev_entry *entry; + unsigned long flags; + int size = 0; + unsigned n, id, max; + ktime_t now, t; + + max = log->max; + now = ktime_get(); + local_irq_save(flags); + n = (log->next - 1) & (max - 1); + entry = log->entry; + while (n != log->next) { + t = ktime_sub(now, entry[n].when); + id = entry[n].id; + if (id) { + const char *str; + if (id < log->num_strings) + str = log->strings[id]; + else + str = "UNKNOWN"; + size += scnprintf(ev_buf + size, 4096 - size, + "%8d.%03d %08x %s\n", + t.tv.sec, t.tv.nsec / 1000000, + entry[n].arg, str); + } + n = (n - 1) & (max - 1); + } + log->fault = 0; + local_irq_restore(flags); + return simple_read_from_buffer(buf, count, ppos, ev_buf, size); +} + +static void ev_log_write(struct ev_log *log, unsigned id, unsigned arg) +{ + struct ev_entry *entry; + unsigned long flags; + local_irq_save(flags); + + if (log->fault) { + if (log->fault == 1) + goto done; + log->fault--; + } + + entry = log->entry + log->next; + entry->when = ktime_get(); + entry->id = id; + entry->arg = arg; + log->next = (log->next + 1) & (log->max - 1); +done: + local_irq_restore(flags); +} + +static void ev_log_freeze(struct ev_log *log, unsigned count) +{ + unsigned long flags; + local_irq_save(flags); + log->fault = count; + local_irq_restore(flags); +} + +static int ev_log_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static const struct file_operations ev_log_ops = { + .read = ev_log_read, + .open = ev_log_open, + .llseek = default_llseek, +}; + +static int ev_log_init(struct ev_log *log) +{ + debugfs_create_file(log->name, 0444, 0, log, &ev_log_ops); + return 0; +} + diff --git a/trunk/drivers/staging/dream/qdsp5/snd.c b/trunk/drivers/staging/dream/qdsp5/snd.c new file mode 100644 index 000000000000..e0f2f7bca29e --- /dev/null +++ b/trunk/drivers/staging/dream/qdsp5/snd.c @@ -0,0 +1,280 @@ +/* arch/arm/mach-msm/qdsp5/snd.c + * + * interface to "snd" service on the baseband cpu + * + * Copyright (C) 2008 HTC Corporation + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +struct snd_ctxt { + struct mutex lock; + int opened; + struct msm_rpc_endpoint *ept; + struct msm_snd_endpoints *snd_epts; +}; + +static struct snd_ctxt the_snd; + +#define RPC_SND_PROG 0x30000002 +#define RPC_SND_CB_PROG 0x31000002 +#if CONFIG_MSM_AMSS_VERSION == 6210 +#define RPC_SND_VERS 0x94756085 /* 2490720389 */ +#elif (CONFIG_MSM_AMSS_VERSION == 6220) || \ + (CONFIG_MSM_AMSS_VERSION == 6225) +#define RPC_SND_VERS 0xaa2b1a44 /* 2854951492 */ +#elif CONFIG_MSM_AMSS_VERSION == 6350 +#define RPC_SND_VERS MSM_RPC_VERS(1,0) +#endif + +#define SND_SET_DEVICE_PROC 2 +#define SND_SET_VOLUME_PROC 3 + +struct rpc_snd_set_device_args { + uint32_t device; + uint32_t ear_mute; + uint32_t mic_mute; + + uint32_t cb_func; + uint32_t client_data; +}; + +struct rpc_snd_set_volume_args { + uint32_t device; + uint32_t method; + uint32_t volume; + + uint32_t cb_func; + uint32_t client_data; +}; + +struct snd_set_device_msg { + struct rpc_request_hdr hdr; + struct rpc_snd_set_device_args args; +}; + +struct snd_set_volume_msg { + struct rpc_request_hdr hdr; + struct rpc_snd_set_volume_args args; +}; + +struct snd_endpoint *get_snd_endpoints(int *size); + +static inline int check_mute(int mute) +{ + return (mute == SND_MUTE_MUTED || + mute == SND_MUTE_UNMUTED) ? 0 : -EINVAL; +} + +static int get_endpoint(struct snd_ctxt *snd, unsigned long arg) +{ + int rc = 0, index; + struct msm_snd_endpoint ept; + + if (copy_from_user(&ept, (void __user *)arg, sizeof(ept))) { + pr_err("snd_ioctl get endpoint: invalid read pointer.\n"); + return -EFAULT; + } + + index = ept.id; + if (index < 0 || index >= snd->snd_epts->num) { + pr_err("snd_ioctl get endpoint: invalid index!\n"); + return -EINVAL; + } + + ept.id = snd->snd_epts->endpoints[index].id; + strncpy(ept.name, + snd->snd_epts->endpoints[index].name, + sizeof(ept.name)); + + if (copy_to_user((void __user *)arg, &ept, sizeof(ept))) { + pr_err("snd_ioctl get endpoint: invalid write pointer.\n"); + rc = -EFAULT; + } + + return rc; +} + +static long snd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct snd_set_device_msg dmsg; + struct snd_set_volume_msg vmsg; + struct msm_snd_device_config dev; + struct msm_snd_volume_config vol; + struct snd_ctxt *snd = file->private_data; + int rc = 0; + + mutex_lock(&snd->lock); + switch (cmd) { + case SND_SET_DEVICE: + if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) { + pr_err("snd_ioctl set device: invalid pointer.\n"); + rc = -EFAULT; + break; + } + + dmsg.args.device = cpu_to_be32(dev.device); + dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute); + dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute); + if (check_mute(dev.ear_mute) < 0 || + check_mute(dev.mic_mute) < 0) { + pr_err("snd_ioctl set device: invalid mute status.\n"); + rc = -EINVAL; + break; + } + dmsg.args.cb_func = -1; + dmsg.args.client_data = 0; + + pr_info("snd_set_device %d %d %d\n", dev.device, + dev.ear_mute, dev.mic_mute); + + rc = msm_rpc_call(snd->ept, + SND_SET_DEVICE_PROC, + &dmsg, sizeof(dmsg), 5 * HZ); + break; + + case SND_SET_VOLUME: + if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) { + pr_err("snd_ioctl set volume: invalid pointer.\n"); + rc = -EFAULT; + break; + } + + vmsg.args.device = cpu_to_be32(vol.device); + vmsg.args.method = cpu_to_be32(vol.method); + if (vol.method != SND_METHOD_VOICE) { + pr_err("snd_ioctl set volume: invalid method.\n"); + rc = -EINVAL; + break; + } + + vmsg.args.volume = cpu_to_be32(vol.volume); + vmsg.args.cb_func = -1; + vmsg.args.client_data = 0; + + pr_info("snd_set_volume %d %d %d\n", vol.device, + vol.method, vol.volume); + + rc = msm_rpc_call(snd->ept, + SND_SET_VOLUME_PROC, + &vmsg, sizeof(vmsg), 5 * HZ); + break; + + case SND_GET_NUM_ENDPOINTS: + if (copy_to_user((void __user *)arg, + &snd->snd_epts->num, sizeof(unsigned))) { + pr_err("snd_ioctl get endpoint: invalid pointer.\n"); + rc = -EFAULT; + } + break; + + case SND_GET_ENDPOINT: + rc = get_endpoint(snd, arg); + break; + + default: + pr_err("snd_ioctl unknown command.\n"); + rc = -EINVAL; + break; + } + mutex_unlock(&snd->lock); + + return rc; +} + +static int snd_release(struct inode *inode, struct file *file) +{ + struct snd_ctxt *snd = file->private_data; + + mutex_lock(&snd->lock); + snd->opened = 0; + mutex_unlock(&snd->lock); + return 0; +} + +static int snd_open(struct inode *inode, struct file *file) +{ + struct snd_ctxt *snd = &the_snd; + int rc = 0; + + mutex_lock(&snd->lock); + if (snd->opened == 0) { + if (snd->ept == NULL) { + snd->ept = msm_rpc_connect(RPC_SND_PROG, RPC_SND_VERS, + MSM_RPC_UNINTERRUPTIBLE); + if (IS_ERR(snd->ept)) { + rc = PTR_ERR(snd->ept); + snd->ept = NULL; + pr_err("snd: failed to connect snd svc\n"); + goto err; + } + } + file->private_data = snd; + snd->opened = 1; + } else { + pr_err("snd already opened.\n"); + rc = -EBUSY; + } + +err: + mutex_unlock(&snd->lock); + return rc; +} + +static struct file_operations snd_fops = { + .owner = THIS_MODULE, + .open = snd_open, + .release = snd_release, + .unlocked_ioctl = snd_ioctl, + .llseek = noop_llseek, +}; + +struct miscdevice snd_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_snd", + .fops = &snd_fops, +}; + +static int snd_probe(struct platform_device *pdev) +{ + struct snd_ctxt *snd = &the_snd; + mutex_init(&snd->lock); + snd->snd_epts = (struct msm_snd_endpoints *)pdev->dev.platform_data; + return misc_register(&snd_misc); +} + +static struct platform_driver snd_plat_driver = { + .probe = snd_probe, + .driver = { + .name = "msm_snd", + .owner = THIS_MODULE, + }, +}; + +static int __init snd_init(void) +{ + return platform_driver_register(&snd_plat_driver); +} + +module_init(snd_init); diff --git a/trunk/drivers/staging/dream/synaptics_i2c_rmi.c b/trunk/drivers/staging/dream/synaptics_i2c_rmi.c new file mode 100644 index 000000000000..3320359408a9 --- /dev/null +++ b/trunk/drivers/staging/dream/synaptics_i2c_rmi.c @@ -0,0 +1,649 @@ +/* + * Support for synaptics touchscreen. + * + * Copyright (C) 2007 Google, Inc. + * Author: Arve HjønnevÃ¥g + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * http://www.synaptics.com/sites/default/files/511_000099_01F.pdf + */ + +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include +#include +#include +#include +#include +#include +#include "synaptics_i2c_rmi.h" + +static struct workqueue_struct *synaptics_wq; + +struct synaptics_ts_data { + u16 addr; + struct i2c_client *client; + struct input_dev *input_dev; + int use_irq; + struct hrtimer timer; + struct work_struct work; + u16 max[2]; + int snap_state[2][2]; + int snap_down_on[2]; + int snap_down_off[2]; + int snap_up_on[2]; + int snap_up_off[2]; + int snap_down[2]; + int snap_up[2]; + u32 flags; + int (*power)(int on); +#ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend; +#endif +}; + +static int i2c_set(struct synaptics_ts_data *ts, u8 reg, u8 val, char *msg) +{ + int ret = i2c_smbus_write_byte_data(ts->client, reg, val); + if (ret < 0) + pr_err("i2c_smbus_write_byte_data failed (%s)\n", msg); + return ret; +} + +static int i2c_read(struct synaptics_ts_data *ts, u8 reg, char *msg) +{ + int ret = i2c_smbus_read_byte_data(ts->client, reg); + if (ret < 0) + pr_err("i2c_smbus_read_byte_data failed (%s)\n", msg); + return ret; +} +#ifdef CONFIG_HAS_EARLYSUSPEND +static void synaptics_ts_early_suspend(struct early_suspend *h); +static void synaptics_ts_late_resume(struct early_suspend *h); +#endif + +static int synaptics_init_panel(struct synaptics_ts_data *ts) +{ + int ret; + + ret = i2c_set(ts, 0xff, 0x10, "set page select"); + if (ret == 0) + ret = i2c_set(ts, 0x41, 0x04, "set No Clip Z"); + + ret = i2c_set(ts, 0xff, 0x04, "fallback page select"); + ret = i2c_set(ts, 0xf0, 0x81, "select 80 reports per second"); + return ret; +} + +static void decode_report(struct synaptics_ts_data *ts, u8 *buf) +{ +/* + * This sensor sends two 6-byte absolute finger reports, an optional + * 2-byte relative report followed by a status byte. This function + * reads the two finger reports and transforms the coordinates + * according the platform data so they can be aligned with the lcd + * behind the touchscreen. Typically we flip the y-axis since the + * sensor uses the bottom left corner as the origin, but if the sensor + * is mounted upside down the platform data will request that the + * x-axis should be flipped instead. The snap to inactive edge border + * are used to allow tapping the edges of the screen on the G1. The + * active area of the touchscreen is smaller than the lcd. When the + * finger gets close the edge of the screen we snap it to the + * edge. This allows ui elements at the edge of the screen to be hit, + * and it prevents hitting ui elements that are not at the edge of the + * screen when the finger is touching the edge. + */ + int pos[2][2]; + int f, a; + int base = 2; + int z = buf[1]; + int finger = buf[0] & 7; + + for (f = 0; f < 2; f++) { + u32 flip_flag = SYNAPTICS_FLIP_X; + for (a = 0; a < 2; a++) { + int p = buf[base + 1]; + p |= (u16)(buf[base] & 0x1f) << 8; + if (ts->flags & flip_flag) + p = ts->max[a] - p; + if (ts->flags & SYNAPTICS_SNAP_TO_INACTIVE_EDGE) { + if (ts->snap_state[f][a]) { + if (p <= ts->snap_down_off[a]) + p = ts->snap_down[a]; + else if (p >= ts->snap_up_off[a]) + p = ts->snap_up[a]; + else + ts->snap_state[f][a] = 0; + } else { + if (p <= ts->snap_down_on[a]) { + p = ts->snap_down[a]; + ts->snap_state[f][a] = 1; + } else if (p >= ts->snap_up_on[a]) { + p = ts->snap_up[a]; + ts->snap_state[f][a] = 1; + } + } + } + pos[f][a] = p; + base += 2; + flip_flag <<= 1; + } + base += 2; + if (ts->flags & SYNAPTICS_SWAP_XY) + swap(pos[f][0], pos[f][1]); + } + if (z) { + input_report_abs(ts->input_dev, ABS_X, pos[0][0]); + input_report_abs(ts->input_dev, ABS_Y, pos[0][1]); + } + input_report_abs(ts->input_dev, ABS_PRESSURE, z); + input_report_key(ts->input_dev, BTN_TOUCH, finger); + input_sync(ts->input_dev); +} + +static void synaptics_ts_work_func(struct work_struct *work) +{ + int i; + int ret; + int bad_data = 0; + struct i2c_msg msg[2]; + u8 start_reg = 0; + u8 buf[15]; + struct synaptics_ts_data *ts = + container_of(work, struct synaptics_ts_data, work); + + msg[0].addr = ts->client->addr; + msg[0].flags = 0; + msg[0].len = 1; + msg[0].buf = &start_reg; + msg[1].addr = ts->client->addr; + msg[1].flags = I2C_M_RD; + msg[1].len = sizeof(buf); + msg[1].buf = buf; + + for (i = 0; i < ((ts->use_irq && !bad_data) ? 1 : 10); i++) { + ret = i2c_transfer(ts->client->adapter, msg, 2); + if (ret < 0) { + pr_err("ts_work: i2c_transfer failed\n"); + bad_data = 1; + continue; + } + if ((buf[14] & 0xc0) != 0x40) { + pr_warning("synaptics_ts_work_func:" + " bad read %x %x %x %x %x %x %x %x %x" + " %x %x %x %x %x %x, ret %d\n", + buf[0], buf[1], buf[2], buf[3], + buf[4], buf[5], buf[6], buf[7], + buf[8], buf[9], buf[10], buf[11], + buf[12], buf[13], buf[14], ret); + if (bad_data) + synaptics_init_panel(ts); + bad_data = 1; + continue; + } + bad_data = 0; + if ((buf[14] & 1) == 0) + break; + + decode_report(ts, buf); + } +} + +static enum hrtimer_restart synaptics_ts_timer_func(struct hrtimer *timer) +{ + struct synaptics_ts_data *ts = + container_of(timer, struct synaptics_ts_data, timer); + + queue_work(synaptics_wq, &ts->work); + + hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL); + return HRTIMER_NORESTART; +} + +static irqreturn_t synaptics_ts_irq_handler(int irq, void *dev_id) +{ + struct synaptics_ts_data *ts = dev_id; + + synaptics_ts_work_func(&ts->work); + return IRQ_HANDLED; +} + +static int detect(struct synaptics_ts_data *ts, u32 *panel_version) +{ + int ret; + int retry = 10; + + ret = i2c_set(ts, 0xf4, 0x01, "reset device"); + + while (retry-- > 0) { + ret = i2c_smbus_read_byte_data(ts->client, 0xe4); + if (ret >= 0) + break; + msleep(100); + } + if (ret < 0) { + pr_err("i2c_smbus_read_byte_data failed\n"); + return ret; + } + + *panel_version = ret << 8; + ret = i2c_read(ts, 0xe5, "product minor"); + if (ret < 0) + return ret; + *panel_version |= ret; + + ret = i2c_read(ts, 0xe3, "property"); + if (ret < 0) + return ret; + + pr_info("synaptics: version %x, product property %x\n", + *panel_version, ret); + return 0; +} + +static void compute_areas(struct synaptics_ts_data *ts, + struct synaptics_i2c_rmi_platform_data *pdata, + u16 max_x, u16 max_y) +{ + int inactive_area_left; + int inactive_area_right; + int inactive_area_top; + int inactive_area_bottom; + int snap_left_on; + int snap_left_off; + int snap_right_on; + int snap_right_off; + int snap_top_on; + int snap_top_off; + int snap_bottom_on; + int snap_bottom_off; + int fuzz_x; + int fuzz_y; + int fuzz_p; + int fuzz_w; + int swapped = !!(ts->flags & SYNAPTICS_SWAP_XY); + + inactive_area_left = pdata->inactive_left; + inactive_area_right = pdata->inactive_right; + inactive_area_top = pdata->inactive_top; + inactive_area_bottom = pdata->inactive_bottom; + snap_left_on = pdata->snap_left_on; + snap_left_off = pdata->snap_left_off; + snap_right_on = pdata->snap_right_on; + snap_right_off = pdata->snap_right_off; + snap_top_on = pdata->snap_top_on; + snap_top_off = pdata->snap_top_off; + snap_bottom_on = pdata->snap_bottom_on; + snap_bottom_off = pdata->snap_bottom_off; + fuzz_x = pdata->fuzz_x; + fuzz_y = pdata->fuzz_y; + fuzz_p = pdata->fuzz_p; + fuzz_w = pdata->fuzz_w; + + inactive_area_left = inactive_area_left * max_x / 0x10000; + inactive_area_right = inactive_area_right * max_x / 0x10000; + inactive_area_top = inactive_area_top * max_y / 0x10000; + inactive_area_bottom = inactive_area_bottom * max_y / 0x10000; + snap_left_on = snap_left_on * max_x / 0x10000; + snap_left_off = snap_left_off * max_x / 0x10000; + snap_right_on = snap_right_on * max_x / 0x10000; + snap_right_off = snap_right_off * max_x / 0x10000; + snap_top_on = snap_top_on * max_y / 0x10000; + snap_top_off = snap_top_off * max_y / 0x10000; + snap_bottom_on = snap_bottom_on * max_y / 0x10000; + snap_bottom_off = snap_bottom_off * max_y / 0x10000; + fuzz_x = fuzz_x * max_x / 0x10000; + fuzz_y = fuzz_y * max_y / 0x10000; + + + ts->snap_down[swapped] = -inactive_area_left; + ts->snap_up[swapped] = max_x + inactive_area_right; + ts->snap_down[!swapped] = -inactive_area_top; + ts->snap_up[!swapped] = max_y + inactive_area_bottom; + ts->snap_down_on[swapped] = snap_left_on; + ts->snap_down_off[swapped] = snap_left_off; + ts->snap_up_on[swapped] = max_x - snap_right_on; + ts->snap_up_off[swapped] = max_x - snap_right_off; + ts->snap_down_on[!swapped] = snap_top_on; + ts->snap_down_off[!swapped] = snap_top_off; + ts->snap_up_on[!swapped] = max_y - snap_bottom_on; + ts->snap_up_off[!swapped] = max_y - snap_bottom_off; + pr_info("synaptics_ts_probe: max_x %d, max_y %d\n", max_x, max_y); + pr_info("synaptics_ts_probe: inactive_x %d %d, inactive_y %d %d\n", + inactive_area_left, inactive_area_right, + inactive_area_top, inactive_area_bottom); + pr_info("synaptics_ts_probe: snap_x %d-%d %d-%d, snap_y %d-%d %d-%d\n", + snap_left_on, snap_left_off, snap_right_on, snap_right_off, + snap_top_on, snap_top_off, snap_bottom_on, snap_bottom_off); + + input_set_abs_params(ts->input_dev, ABS_X, + -inactive_area_left, max_x + inactive_area_right, + fuzz_x, 0); + input_set_abs_params(ts->input_dev, ABS_Y, + -inactive_area_top, max_y + inactive_area_bottom, + fuzz_y, 0); + input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, fuzz_p, 0); +} + +static struct synaptics_i2c_rmi_platform_data fake_pdata; + +static int __devinit synaptics_ts_probe( + struct i2c_client *client, const struct i2c_device_id *id) +{ + struct synaptics_ts_data *ts; + u8 buf0[4]; + u8 buf1[8]; + struct i2c_msg msg[2]; + int ret = 0; + struct synaptics_i2c_rmi_platform_data *pdata; + u32 panel_version = 0; + u16 max_x, max_y; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + pr_err("synaptics_ts_probe: need I2C_FUNC_I2C\n"); + ret = -ENODEV; + goto err_check_functionality_failed; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) { + pr_err("synaptics_ts_probe: need I2C_FUNC_SMBUS_WORD_DATA\n"); + ret = -ENODEV; + goto err_check_functionality_failed; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) { + pr_err("synaptics_ts_probe: need I2C_FUNC_SMBUS_WORD_DATA\n"); + ret = -ENODEV; + goto err_check_functionality_failed; + } + + ts = kzalloc(sizeof(*ts), GFP_KERNEL); + if (ts == NULL) { + ret = -ENOMEM; + goto err_alloc_data_failed; + } + INIT_WORK(&ts->work, synaptics_ts_work_func); + ts->client = client; + i2c_set_clientdata(client, ts); + pdata = client->dev.platform_data; + if (pdata) + ts->power = pdata->power; + else + pdata = &fake_pdata; + + if (ts->power) { + ret = ts->power(1); + if (ret < 0) { + pr_err("synaptics_ts_probe power on failed\n"); + goto err_power_failed; + } + } + + ret = detect(ts, &panel_version); + if (ret) + goto err_detect_failed; + + while (pdata->version > panel_version) + pdata++; + ts->flags = pdata->flags; + + ret = i2c_read(ts, 0xf0, "device control"); + if (ret < 0) + goto err_detect_failed; + pr_info("synaptics: device control %x\n", ret); + + ret = i2c_read(ts, 0xf1, "interrupt enable"); + if (ret < 0) + goto err_detect_failed; + pr_info("synaptics_ts_probe: interrupt enable %x\n", ret); + + ret = i2c_set(ts, 0xf1, 0, "disable interrupt"); + if (ret < 0) + goto err_detect_failed; + + msg[0].addr = ts->client->addr; + msg[0].flags = 0; + msg[0].len = 1; + msg[0].buf = buf0; + buf0[0] = 0xe0; + msg[1].addr = ts->client->addr; + msg[1].flags = I2C_M_RD; + msg[1].len = 8; + msg[1].buf = buf1; + ret = i2c_transfer(ts->client->adapter, msg, 2); + if (ret < 0) { + pr_err("i2c_transfer failed\n"); + goto err_detect_failed; + } + pr_info("synaptics_ts_probe: 0xe0: %x %x %x %x %x %x %x %x\n", + buf1[0], buf1[1], buf1[2], buf1[3], + buf1[4], buf1[5], buf1[6], buf1[7]); + + ret = i2c_set(ts, 0xff, 0x10, "page select = 0x10"); + if (ret < 0) + goto err_detect_failed; + + ret = i2c_smbus_read_word_data(ts->client, 0x04); + if (ret < 0) { + pr_err("i2c_smbus_read_word_data failed\n"); + goto err_detect_failed; + } + ts->max[0] = max_x = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8); + ret = i2c_smbus_read_word_data(ts->client, 0x06); + if (ret < 0) { + pr_err("i2c_smbus_read_word_data failed\n"); + goto err_detect_failed; + } + ts->max[1] = max_y = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8); + if (ts->flags & SYNAPTICS_SWAP_XY) + swap(max_x, max_y); + + /* will also switch back to page 0x04 */ + ret = synaptics_init_panel(ts); + if (ret < 0) { + pr_err("synaptics_init_panel failed\n"); + goto err_detect_failed; + } + + ts->input_dev = input_allocate_device(); + if (ts->input_dev == NULL) { + ret = -ENOMEM; + pr_err("synaptics: Failed to allocate input device\n"); + goto err_input_dev_alloc_failed; + } + ts->input_dev->name = "synaptics-rmi-touchscreen"; + ts->input_dev->phys = "msm/input0"; + ts->input_dev->id.bustype = BUS_I2C; + + __set_bit(EV_SYN, ts->input_dev->evbit); + __set_bit(EV_KEY, ts->input_dev->evbit); + __set_bit(BTN_TOUCH, ts->input_dev->keybit); + __set_bit(EV_ABS, ts->input_dev->evbit); + + compute_areas(ts, pdata, max_x, max_y); + + + ret = input_register_device(ts->input_dev); + if (ret) { + pr_err("synaptics: Unable to register %s input device\n", + ts->input_dev->name); + goto err_input_register_device_failed; + } + if (client->irq) { + ret = request_threaded_irq(client->irq, NULL, + synaptics_ts_irq_handler, + IRQF_TRIGGER_LOW|IRQF_ONESHOT, + client->name, ts); + if (ret == 0) { + ret = i2c_set(ts, 0xf1, 0x01, "enable abs int"); + if (ret) + free_irq(client->irq, ts); + } + if (ret == 0) + ts->use_irq = 1; + else + dev_err(&client->dev, "request_irq failed\n"); + } + if (!ts->use_irq) { + hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + ts->timer.function = synaptics_ts_timer_func; + hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); + } +#ifdef CONFIG_HAS_EARLYSUSPEND + ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + ts->early_suspend.suspend = synaptics_ts_early_suspend; + ts->early_suspend.resume = synaptics_ts_late_resume; + register_early_suspend(&ts->early_suspend); +#endif + + pr_info("synaptics: Start touchscreen %s in %s mode\n", + ts->input_dev->name, ts->use_irq ? "interrupt" : "polling"); + + return 0; + +err_input_register_device_failed: + input_free_device(ts->input_dev); + +err_input_dev_alloc_failed: +err_detect_failed: +err_power_failed: + kfree(ts); +err_alloc_data_failed: +err_check_functionality_failed: + return ret; +} + +static int synaptics_ts_remove(struct i2c_client *client) +{ + struct synaptics_ts_data *ts = i2c_get_clientdata(client); +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&ts->early_suspend); +#endif + if (ts->use_irq) + free_irq(client->irq, ts); + else + hrtimer_cancel(&ts->timer); + input_unregister_device(ts->input_dev); + kfree(ts); + return 0; +} + +#ifdef CONFIG_PM +static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg) +{ + int ret; + struct synaptics_ts_data *ts = i2c_get_clientdata(client); + + if (ts->use_irq) + disable_irq(client->irq); + else + hrtimer_cancel(&ts->timer); + ret = cancel_work_sync(&ts->work); + if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */ + enable_irq(client->irq); + i2c_set(ts, 0xf1, 0, "disable interrupt"); + i2c_set(ts, 0xf0, 0x86, "deep sleep"); + + if (ts->power) { + ret = ts->power(0); + if (ret < 0) + pr_err("synaptics_ts_suspend power off failed\n"); + } + return 0; +} + +static int synaptics_ts_resume(struct i2c_client *client) +{ + int ret; + struct synaptics_ts_data *ts = i2c_get_clientdata(client); + + if (ts->power) { + ret = ts->power(1); + if (ret < 0) + pr_err("synaptics_ts_resume power on failed\n"); + } + + synaptics_init_panel(ts); + + if (ts->use_irq) { + enable_irq(client->irq); + i2c_set(ts, 0xf1, 0x01, "enable abs int"); + } else + hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); + + return 0; +} + +#ifdef CONFIG_HAS_EARLYSUSPEND +static void synaptics_ts_early_suspend(struct early_suspend *h) +{ + struct synaptics_ts_data *ts; + ts = container_of(h, struct synaptics_ts_data, early_suspend); + synaptics_ts_suspend(ts->client, PMSG_SUSPEND); +} + +static void synaptics_ts_late_resume(struct early_suspend *h) +{ + struct synaptics_ts_data *ts; + ts = container_of(h, struct synaptics_ts_data, early_suspend); + synaptics_ts_resume(ts->client); +} +#endif +#else +#define synaptics_ts_suspend NULL +#define synaptics_ts_resume NULL +#endif + + + +static const struct i2c_device_id synaptics_ts_id[] = { + { SYNAPTICS_I2C_RMI_NAME, 0 }, + { } +}; + +static struct i2c_driver synaptics_ts_driver = { + .probe = synaptics_ts_probe, + .remove = synaptics_ts_remove, +#ifndef CONFIG_HAS_EARLYSUSPEND + .suspend = synaptics_ts_suspend, + .resume = synaptics_ts_resume, +#endif + .id_table = synaptics_ts_id, + .driver = { + .name = SYNAPTICS_I2C_RMI_NAME, + }, +}; + +static int __devinit synaptics_ts_init(void) +{ + synaptics_wq = create_singlethread_workqueue("synaptics_wq"); + if (!synaptics_wq) + return -ENOMEM; + return i2c_add_driver(&synaptics_ts_driver); +} + +static void __exit synaptics_ts_exit(void) +{ + i2c_del_driver(&synaptics_ts_driver); + if (synaptics_wq) + destroy_workqueue(synaptics_wq); +} + +module_init(synaptics_ts_init); +module_exit(synaptics_ts_exit); + +MODULE_DESCRIPTION("Synaptics Touchscreen Driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Arve HjønnevÃ¥g "); diff --git a/trunk/drivers/staging/dream/synaptics_i2c_rmi.h b/trunk/drivers/staging/dream/synaptics_i2c_rmi.h new file mode 100644 index 000000000000..ca51b2fc564d --- /dev/null +++ b/trunk/drivers/staging/dream/synaptics_i2c_rmi.h @@ -0,0 +1,53 @@ +/* + * include/linux/synaptics_i2c_rmi.h - platform data structure for f75375s sensor + * + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _LINUX_SYNAPTICS_I2C_RMI_H +#define _LINUX_SYNAPTICS_I2C_RMI_H + +#define SYNAPTICS_I2C_RMI_NAME "synaptics-rmi-ts" + +enum { + SYNAPTICS_FLIP_X = 1UL << 0, + SYNAPTICS_FLIP_Y = 1UL << 1, + SYNAPTICS_SWAP_XY = 1UL << 2, + SYNAPTICS_SNAP_TO_INACTIVE_EDGE = 1UL << 3, +}; + +struct synaptics_i2c_rmi_platform_data { + uint32_t version; /* Use this entry for panels with */ + /* (major << 8 | minor) version or above. */ + /* If non-zero another array entry follows */ + int (*power)(int on); /* Only valid in first array entry */ + uint32_t flags; + uint32_t inactive_left; /* 0x10000 = screen width */ + uint32_t inactive_right; /* 0x10000 = screen width */ + uint32_t inactive_top; /* 0x10000 = screen height */ + uint32_t inactive_bottom; /* 0x10000 = screen height */ + uint32_t snap_left_on; /* 0x10000 = screen width */ + uint32_t snap_left_off; /* 0x10000 = screen width */ + uint32_t snap_right_on; /* 0x10000 = screen width */ + uint32_t snap_right_off; /* 0x10000 = screen width */ + uint32_t snap_top_on; /* 0x10000 = screen height */ + uint32_t snap_top_off; /* 0x10000 = screen height */ + uint32_t snap_bottom_on; /* 0x10000 = screen height */ + uint32_t snap_bottom_off; /* 0x10000 = screen height */ + uint32_t fuzz_x; /* 0x10000 = screen width */ + uint32_t fuzz_y; /* 0x10000 = screen height */ + int fuzz_p; + int fuzz_w; +}; + +#endif /* _LINUX_SYNAPTICS_I2C_RMI_H */ diff --git a/trunk/drivers/staging/pohmelfs/inode.c b/trunk/drivers/staging/pohmelfs/inode.c index 61685ccceda8..c62d30017c07 100644 --- a/trunk/drivers/staging/pohmelfs/inode.c +++ b/trunk/drivers/staging/pohmelfs/inode.c @@ -1937,10 +1937,11 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent) /* * Some VFS magic here... */ -static struct dentry *pohmelfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int pohmelfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_nodev(fs_type, flags, data, pohmelfs_fill_super); + return get_sb_nodev(fs_type, flags, data, pohmelfs_fill_super, + mnt); } /* @@ -1957,7 +1958,7 @@ static void pohmelfs_kill_super(struct super_block *sb) static struct file_system_type pohmel_fs_type = { .owner = THIS_MODULE, .name = "pohmel", - .mount = pohmelfs_mount, + .get_sb = pohmelfs_get_sb, .kill_sb = pohmelfs_kill_super, }; diff --git a/trunk/drivers/staging/smbfs/inode.c b/trunk/drivers/staging/smbfs/inode.c index f9c493591ce7..552951aa7498 100644 --- a/trunk/drivers/staging/smbfs/inode.c +++ b/trunk/drivers/staging/smbfs/inode.c @@ -793,16 +793,16 @@ smb_notify_change(struct dentry *dentry, struct iattr *attr) return error; } -static struct dentry *smb_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int smb_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_nodev(fs_type, flags, data, smb_fill_super); + return get_sb_nodev(fs_type, flags, data, smb_fill_super, mnt); } static struct file_system_type smb_fs_type = { .owner = THIS_MODULE, .name = "smbfs", - .mount = smb_mount, + .get_sb = smb_get_sb, .kill_sb = kill_anon_super, .fs_flags = FS_BINARY_MOUNTDATA, }; diff --git a/trunk/drivers/usb/core/inode.c b/trunk/drivers/usb/core/inode.c index 9819a4cc3b26..e2f63c0ea09d 100644 --- a/trunk/drivers/usb/core/inode.c +++ b/trunk/drivers/usb/core/inode.c @@ -574,16 +574,16 @@ static void fs_remove_file (struct dentry *dentry) /* --------------------------------------------------------------------- */ -static struct dentry *usb_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int usb_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_single(fs_type, flags, data, usbfs_fill_super); + return get_sb_single(fs_type, flags, data, usbfs_fill_super, mnt); } static struct file_system_type usb_fs_type = { .owner = THIS_MODULE, .name = "usbfs", - .mount = usb_mount, + .get_sb = usb_get_sb, .kill_sb = kill_litter_super, }; diff --git a/trunk/drivers/usb/gadget/f_fs.c b/trunk/drivers/usb/gadget/f_fs.c index 4a830df4fc31..f276e9594f00 100644 --- a/trunk/drivers/usb/gadget/f_fs.c +++ b/trunk/drivers/usb/gadget/f_fs.c @@ -1176,9 +1176,9 @@ static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) /* "mount -t functionfs dev_name /dev/function" ends up here */ -static struct dentry * -ffs_fs_mount(struct file_system_type *t, int flags, - const char *dev_name, void *opts) +static int +ffs_fs_get_sb(struct file_system_type *t, int flags, + const char *dev_name, void *opts, struct vfsmount *mnt) { struct ffs_sb_fill_data data = { .perms = { @@ -1194,14 +1194,14 @@ ffs_fs_mount(struct file_system_type *t, int flags, ret = functionfs_check_dev_callback(dev_name); if (unlikely(ret < 0)) - return ERR_PTR(ret); + return ret; ret = ffs_fs_parse_opts(&data, opts); if (unlikely(ret < 0)) - return ERR_PTR(ret); + return ret; data.dev_name = dev_name; - return mount_single(t, flags, &data, ffs_sb_fill); + return get_sb_single(t, flags, &data, ffs_sb_fill, mnt); } static void @@ -1220,7 +1220,7 @@ ffs_fs_kill_sb(struct super_block *sb) static struct file_system_type ffs_fs_type = { .owner = THIS_MODULE, .name = "functionfs", - .mount = ffs_fs_mount, + .get_sb = ffs_fs_get_sb, .kill_sb = ffs_fs_kill_sb, }; diff --git a/trunk/drivers/usb/gadget/inode.c b/trunk/drivers/usb/gadget/inode.c index 3ed73f49cf18..ba145e7fbe03 100644 --- a/trunk/drivers/usb/gadget/inode.c +++ b/trunk/drivers/usb/gadget/inode.c @@ -2097,11 +2097,11 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent) } /* "mount -t gadgetfs path /dev/gadget" ends up here */ -static struct dentry * -gadgetfs_mount (struct file_system_type *t, int flags, - const char *path, void *opts) +static int +gadgetfs_get_sb (struct file_system_type *t, int flags, + const char *path, void *opts, struct vfsmount *mnt) { - return mount_single (t, flags, opts, gadgetfs_fill_super); + return get_sb_single (t, flags, opts, gadgetfs_fill_super, mnt); } static void @@ -2119,7 +2119,7 @@ gadgetfs_kill_sb (struct super_block *sb) static struct file_system_type gadgetfs_type = { .owner = THIS_MODULE, .name = shortname, - .mount = gadgetfs_mount, + .get_sb = gadgetfs_get_sb, .kill_sb = gadgetfs_kill_sb, }; diff --git a/trunk/drivers/usb/gadget/u_ether.c b/trunk/drivers/usb/gadget/u_ether.c index cb23355f52d3..6bb876d65252 100644 --- a/trunk/drivers/usb/gadget/u_ether.c +++ b/trunk/drivers/usb/gadget/u_ether.c @@ -797,6 +797,7 @@ int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) * - iff DATA transfer is active, carrier is "on" * - tx queueing enabled if open *and* carrier is "on" */ + netif_stop_queue(net); netif_carrier_off(net); dev->gadget = g; @@ -811,7 +812,6 @@ int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) INFO(dev, "MAC %pM\n", net->dev_addr); INFO(dev, "HOST MAC %pM\n", dev->host_mac); - netif_stop_queue(net); the_dev = dev; } diff --git a/trunk/drivers/usb/host/Kconfig b/trunk/drivers/usb/host/Kconfig index 2391c396ca32..bf2e7d234533 100644 --- a/trunk/drivers/usb/host/Kconfig +++ b/trunk/drivers/usb/host/Kconfig @@ -93,9 +93,8 @@ config USB_EHCI_TT_NEWSCHED config USB_EHCI_BIG_ENDIAN_MMIO bool - depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || \ - ARCH_IXP4XX || XPS_USB_HCD_XILINX || \ - PPC_MPC512x || CPU_CAVIUM_OCTEON) + depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || ARCH_IXP4XX || \ + XPS_USB_HCD_XILINX || PPC_MPC512x) default y config USB_EHCI_BIG_ENDIAN_DESC @@ -435,28 +434,3 @@ config USB_IMX21_HCD To compile this driver as a module, choose M here: the module will be called "imx21-hcd". -config USB_OCTEON_EHCI - bool "Octeon on-chip EHCI support" - depends on USB && USB_EHCI_HCD && CPU_CAVIUM_OCTEON - default n - select USB_EHCI_BIG_ENDIAN_MMIO - help - Enable support for the Octeon II SOC's on-chip EHCI - controller. It is needed for high-speed (480Mbit/sec) - USB 2.0 device support. All CN6XXX based chips with USB are - supported. - -config USB_OCTEON_OHCI - bool "Octeon on-chip OHCI support" - depends on USB && USB_OHCI_HCD && CPU_CAVIUM_OCTEON - default USB_OCTEON_EHCI - select USB_OHCI_BIG_ENDIAN_MMIO - select USB_OHCI_LITTLE_ENDIAN - help - Enable support for the Octeon II SOC's on-chip OHCI - controller. It is needed for low-speed USB 1.0 device - support. All CN6XXX based chips with USB are supported. - -config USB_OCTEON2_COMMON - bool - default y if USB_OCTEON_EHCI || USB_OCTEON_OHCI diff --git a/trunk/drivers/usb/host/Makefile b/trunk/drivers/usb/host/Makefile index 624a362f2fee..91c5a1bd1026 100644 --- a/trunk/drivers/usb/host/Makefile +++ b/trunk/drivers/usb/host/Makefile @@ -34,4 +34,3 @@ obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o -obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index 502a7e6fef42..2adae8e39bba 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -1211,11 +1211,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_atmel_driver #endif -#ifdef CONFIG_USB_OCTEON_EHCI -#include "ehci-octeon.c" -#define PLATFORM_DRIVER ehci_octeon_driver -#endif - #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ !defined(XILINX_OF_PLATFORM_DRIVER) diff --git a/trunk/drivers/usb/host/ehci-octeon.c b/trunk/drivers/usb/host/ehci-octeon.c deleted file mode 100644 index a31a031178a8..000000000000 --- a/trunk/drivers/usb/host/ehci-octeon.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * EHCI HCD glue for Cavium Octeon II SOCs. - * - * Loosely based on ehci-au1xxx.c - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2010 Cavium Networks - * - */ - -#include - -#include -#include - -#define OCTEON_EHCI_HCD_NAME "octeon-ehci" - -/* Common clock init code. */ -void octeon2_usb_clocks_start(void); -void octeon2_usb_clocks_stop(void); - -static void ehci_octeon_start(void) -{ - union cvmx_uctlx_ehci_ctl ehci_ctl; - - octeon2_usb_clocks_start(); - - ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0)); - /* Use 64-bit addressing. */ - ehci_ctl.s.ehci_64b_addr_en = 1; - ehci_ctl.s.l2c_addr_msb = 0; - ehci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */ - ehci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */ - cvmx_write_csr(CVMX_UCTLX_EHCI_CTL(0), ehci_ctl.u64); -} - -static void ehci_octeon_stop(void) -{ - octeon2_usb_clocks_stop(); -} - -static const struct hc_driver ehci_octeon_hc_driver = { - .description = hcd_name, - .product_desc = "Octeon EHCI", - .hcd_priv_size = sizeof(struct ehci_hcd), - - /* - * generic hardware linkage - */ - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, - - /* - * basic lifecycle operations - */ - .reset = ehci_init, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, - - /* - * scheduling support - */ - .get_frame_number = ehci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, - - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -}; - -static u64 ehci_octeon_dma_mask = DMA_BIT_MASK(64); - -static int ehci_octeon_drv_probe(struct platform_device *pdev) -{ - struct usb_hcd *hcd; - struct ehci_hcd *ehci; - struct resource *res_mem; - int irq; - int ret; - - if (usb_disabled()) - return -ENODEV; - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "No irq assigned\n"); - return -ENODEV; - } - - res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res_mem == NULL) { - dev_err(&pdev->dev, "No register space assigned\n"); - return -ENODEV; - } - - /* - * We can DMA from anywhere. But the descriptors must be in - * the lower 4GB. - */ - pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - pdev->dev.dma_mask = &ehci_octeon_dma_mask; - - hcd = usb_create_hcd(&ehci_octeon_hc_driver, &pdev->dev, "octeon"); - if (!hcd) - return -ENOMEM; - - hcd->rsrc_start = res_mem->start; - hcd->rsrc_len = res_mem->end - res_mem->start + 1; - - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, - OCTEON_EHCI_HCD_NAME)) { - dev_err(&pdev->dev, "request_mem_region failed\n"); - ret = -EBUSY; - goto err1; - } - - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); - if (!hcd->regs) { - dev_err(&pdev->dev, "ioremap failed\n"); - ret = -ENOMEM; - goto err2; - } - - ehci_octeon_start(); - - ehci = hcd_to_ehci(hcd); - - /* Octeon EHCI matches CPU endianness. */ -#ifdef __BIG_ENDIAN - ehci->big_endian_mmio = 1; -#endif - - ehci->caps = hcd->regs; - ehci->regs = hcd->regs + - HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); - /* cache this readonly data; minimize chip reads */ - ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); - - ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); - if (ret) { - dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); - goto err3; - } - - platform_set_drvdata(pdev, hcd); - - /* root ports should always stay powered */ - ehci_port_power(ehci, 1); - - return 0; -err3: - ehci_octeon_stop(); - - iounmap(hcd->regs); -err2: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -err1: - usb_put_hcd(hcd); - return ret; -} - -static int ehci_octeon_drv_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_remove_hcd(hcd); - - ehci_octeon_stop(); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_put_hcd(hcd); - - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static struct platform_driver ehci_octeon_driver = { - .probe = ehci_octeon_drv_probe, - .remove = ehci_octeon_drv_remove, - .shutdown = usb_hcd_platform_shutdown, - .driver = { - .name = OCTEON_EHCI_HCD_NAME, - .owner = THIS_MODULE, - } -}; - -MODULE_ALIAS("platform:" OCTEON_EHCI_HCD_NAME); diff --git a/trunk/drivers/usb/host/octeon2-common.c b/trunk/drivers/usb/host/octeon2-common.c deleted file mode 100644 index 72d672cfcf39..000000000000 --- a/trunk/drivers/usb/host/octeon2-common.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2010 Cavium Networks - */ - -#include -#include - -#include - -#include -#include - -static atomic_t octeon2_usb_clock_start_cnt = ATOMIC_INIT(0); - -void octeon2_usb_clocks_start(void) -{ - u64 div; - union cvmx_uctlx_if_ena if_ena; - union cvmx_uctlx_clk_rst_ctl clk_rst_ctl; - union cvmx_uctlx_uphy_ctl_status uphy_ctl_status; - union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status; - int i; - unsigned long io_clk_64_to_ns; - - if (atomic_inc_return(&octeon2_usb_clock_start_cnt) != 1) - return; - - io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate(); - - /* - * Step 1: Wait for voltages stable. That surely happened - * before starting the kernel. - * - * Step 2: Enable SCLK of UCTL by writing UCTL0_IF_ENA[EN] = 1 - */ - if_ena.u64 = 0; - if_ena.s.en = 1; - cvmx_write_csr(CVMX_UCTLX_IF_ENA(0), if_ena.u64); - - /* Step 3: Configure the reference clock, PHY, and HCLK */ - clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0)); - /* 3a */ - clk_rst_ctl.s.p_por = 1; - clk_rst_ctl.s.hrst = 0; - clk_rst_ctl.s.p_prst = 0; - clk_rst_ctl.s.h_clkdiv_rst = 0; - clk_rst_ctl.s.o_clkdiv_rst = 0; - clk_rst_ctl.s.h_clkdiv_en = 0; - clk_rst_ctl.s.o_clkdiv_en = 0; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* 3b */ - /* 12MHz crystal. */ - clk_rst_ctl.s.p_refclk_sel = 0; - clk_rst_ctl.s.p_refclk_div = 0; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* 3c */ - div = octeon_get_io_clock_rate() / 130000000ull; - - switch (div) { - case 0: - div = 1; - break; - case 1: - case 2: - case 3: - case 4: - break; - case 5: - div = 4; - break; - case 6: - case 7: - div = 6; - break; - case 8: - case 9: - case 10: - case 11: - div = 8; - break; - default: - div = 12; - break; - } - clk_rst_ctl.s.h_div = div; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - /* Read it back, */ - clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0)); - clk_rst_ctl.s.h_clkdiv_en = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - /* 3d */ - clk_rst_ctl.s.h_clkdiv_rst = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* 3e: delay 64 io clocks */ - ndelay(io_clk_64_to_ns); - - /* - * Step 4: Program the power-on reset field in the UCTL - * clock-reset-control register. - */ - clk_rst_ctl.s.p_por = 0; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* Step 5: Wait 1 ms for the PHY clock to start. */ - mdelay(1); - - /* - * Step 6: Program the reset input from automatic test - * equipment field in the UPHY CSR - */ - uphy_ctl_status.u64 = cvmx_read_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0)); - uphy_ctl_status.s.ate_reset = 1; - cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64); - - /* Step 7: Wait for at least 10ns. */ - ndelay(10); - - /* Step 8: Clear the ATE_RESET field in the UPHY CSR. */ - uphy_ctl_status.s.ate_reset = 0; - cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64); - - /* - * Step 9: Wait for at least 20ns for UPHY to output PHY clock - * signals and OHCI_CLK48 - */ - ndelay(20); - - /* Step 10: Configure the OHCI_CLK48 and OHCI_CLK12 clocks. */ - /* 10a */ - clk_rst_ctl.s.o_clkdiv_rst = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* 10b */ - clk_rst_ctl.s.o_clkdiv_en = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* 10c */ - ndelay(io_clk_64_to_ns); - - /* - * Step 11: Program the PHY reset field: - * UCTL0_CLK_RST_CTL[P_PRST] = 1 - */ - clk_rst_ctl.s.p_prst = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* Step 12: Wait 1 uS. */ - udelay(1); - - /* Step 13: Program the HRESET_N field: UCTL0_CLK_RST_CTL[HRST] = 1 */ - clk_rst_ctl.s.hrst = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* Now we can set some other registers. */ - - for (i = 0; i <= 1; i++) { - port_ctl_status.u64 = - cvmx_read_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0)); - /* Set txvreftune to 15 to obtain complient 'eye' diagram. */ - port_ctl_status.s.txvreftune = 15; - cvmx_write_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0), - port_ctl_status.u64); - } -} -EXPORT_SYMBOL(octeon2_usb_clocks_start); - -void octeon2_usb_clocks_stop(void) -{ - union cvmx_uctlx_if_ena if_ena; - - if (atomic_dec_return(&octeon2_usb_clock_start_cnt) != 0) - return; - - if_ena.u64 = 0; - if_ena.s.en = 0; - cvmx_write_csr(CVMX_UCTLX_IF_ENA(0), if_ena.u64); -} -EXPORT_SYMBOL(octeon2_usb_clocks_stop); diff --git a/trunk/drivers/usb/host/ohci-hcd.c b/trunk/drivers/usb/host/ohci-hcd.c index 5179acb7aa2f..f3713f43f3fe 100644 --- a/trunk/drivers/usb/host/ohci-hcd.c +++ b/trunk/drivers/usb/host/ohci-hcd.c @@ -1106,11 +1106,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ohci_hcd_jz4740_driver #endif -#ifdef CONFIG_USB_OCTEON_OHCI -#include "ohci-octeon.c" -#define PLATFORM_DRIVER ohci_octeon_driver -#endif - #if !defined(PCI_DRIVER) && \ !defined(PLATFORM_DRIVER) && \ !defined(OMAP1_PLATFORM_DRIVER) && \ diff --git a/trunk/drivers/usb/host/ohci-octeon.c b/trunk/drivers/usb/host/ohci-octeon.c deleted file mode 100644 index e4ddfaf8870f..000000000000 --- a/trunk/drivers/usb/host/ohci-octeon.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * EHCI HCD glue for Cavium Octeon II SOCs. - * - * Loosely based on ehci-au1xxx.c - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2010 Cavium Networks - * - */ - -#include - -#include -#include - -#define OCTEON_OHCI_HCD_NAME "octeon-ohci" - -/* Common clock init code. */ -void octeon2_usb_clocks_start(void); -void octeon2_usb_clocks_stop(void); - -static void ohci_octeon_hw_start(void) -{ - union cvmx_uctlx_ohci_ctl ohci_ctl; - - octeon2_usb_clocks_start(); - - ohci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_OHCI_CTL(0)); - ohci_ctl.s.l2c_addr_msb = 0; - ohci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */ - ohci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */ - cvmx_write_csr(CVMX_UCTLX_OHCI_CTL(0), ohci_ctl.u64); - -} - -static void ohci_octeon_hw_stop(void) -{ - /* Undo ohci_octeon_start() */ - octeon2_usb_clocks_stop(); -} - -static int __devinit ohci_octeon_start(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - int ret; - - ret = ohci_init(ohci); - - if (ret < 0) - return ret; - - ret = ohci_run(ohci); - - if (ret < 0) { - ohci_err(ohci, "can't start %s", hcd->self.bus_name); - ohci_stop(hcd); - return ret; - } - - return 0; -} - -static const struct hc_driver ohci_octeon_hc_driver = { - .description = hcd_name, - .product_desc = "Octeon OHCI", - .hcd_priv_size = sizeof(struct ohci_hcd), - - /* - * generic hardware linkage - */ - .irq = ohci_irq, - .flags = HCD_USB11 | HCD_MEMORY, - - /* - * basic lifecycle operations - */ - .start = ohci_octeon_start, - .stop = ohci_stop, - .shutdown = ohci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ohci_urb_enqueue, - .urb_dequeue = ohci_urb_dequeue, - .endpoint_disable = ohci_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = ohci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ohci_hub_status_data, - .hub_control = ohci_hub_control, - - .start_port_reset = ohci_start_port_reset, -}; - -static int ohci_octeon_drv_probe(struct platform_device *pdev) -{ - struct usb_hcd *hcd; - struct ohci_hcd *ohci; - void *reg_base; - struct resource *res_mem; - int irq; - int ret; - - if (usb_disabled()) - return -ENODEV; - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "No irq assigned\n"); - return -ENODEV; - } - - res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res_mem == NULL) { - dev_err(&pdev->dev, "No register space assigned\n"); - return -ENODEV; - } - - /* Ohci is a 32-bit device. */ - pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; - - hcd = usb_create_hcd(&ohci_octeon_hc_driver, &pdev->dev, "octeon"); - if (!hcd) - return -ENOMEM; - - hcd->rsrc_start = res_mem->start; - hcd->rsrc_len = res_mem->end - res_mem->start + 1; - - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, - OCTEON_OHCI_HCD_NAME)) { - dev_err(&pdev->dev, "request_mem_region failed\n"); - ret = -EBUSY; - goto err1; - } - - reg_base = ioremap(hcd->rsrc_start, hcd->rsrc_len); - if (!reg_base) { - dev_err(&pdev->dev, "ioremap failed\n"); - ret = -ENOMEM; - goto err2; - } - - ohci_octeon_hw_start(); - - hcd->regs = reg_base; - - ohci = hcd_to_ohci(hcd); - - /* Octeon OHCI matches CPU endianness. */ -#ifdef __BIG_ENDIAN - ohci->flags |= OHCI_QUIRK_BE_MMIO; -#endif - - ohci_hcd_init(ohci); - - ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); - if (ret) { - dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); - goto err3; - } - - platform_set_drvdata(pdev, hcd); - - return 0; - -err3: - ohci_octeon_hw_stop(); - - iounmap(hcd->regs); -err2: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -err1: - usb_put_hcd(hcd); - return ret; -} - -static int ohci_octeon_drv_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_remove_hcd(hcd); - - ohci_octeon_hw_stop(); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_put_hcd(hcd); - - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static struct platform_driver ohci_octeon_driver = { - .probe = ohci_octeon_drv_probe, - .remove = ohci_octeon_drv_remove, - .shutdown = usb_hcd_platform_shutdown, - .driver = { - .name = OCTEON_OHCI_HCD_NAME, - .owner = THIS_MODULE, - } -}; - -MODULE_ALIAS("platform:" OCTEON_OHCI_HCD_NAME); diff --git a/trunk/drivers/watchdog/octeon-wdt-main.c b/trunk/drivers/watchdog/octeon-wdt-main.c index 945ee8300306..909923800a02 100644 --- a/trunk/drivers/watchdog/octeon-wdt-main.c +++ b/trunk/drivers/watchdog/octeon-wdt-main.c @@ -478,7 +478,7 @@ static void octeon_wdt_calc_parameters(int t) countdown_reset = periods > 2 ? periods - 2 : 0; heartbeat = t; - timeout_cnt = ((octeon_get_io_clock_rate() >> 8) * timeout_sec) >> 8; + timeout_cnt = ((octeon_get_clock_rate() >> 8) * timeout_sec) >> 8; } static int octeon_wdt_set_heartbeat(int t) @@ -677,7 +677,7 @@ static int __init octeon_wdt_init(void) max_timeout_sec = 6; do { max_timeout_sec--; - timeout_cnt = ((octeon_get_io_clock_rate() >> 8) * max_timeout_sec) >> 8; + timeout_cnt = ((octeon_get_clock_rate() >> 8) * max_timeout_sec) >> 8; } while (timeout_cnt > 65535); BUG_ON(timeout_cnt == 0); diff --git a/trunk/drivers/xen/xenfs/super.c b/trunk/drivers/xen/xenfs/super.c index f6339d11d59c..d6662b789b6b 100644 --- a/trunk/drivers/xen/xenfs/super.c +++ b/trunk/drivers/xen/xenfs/super.c @@ -121,17 +121,17 @@ static int xenfs_fill_super(struct super_block *sb, void *data, int silent) return rc; } -static int xenfs_mount(struct file_system_type *fs_type, +static int xenfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, - void *data) + void *data, struct vfsmount *mnt) { - return mount_single(fs_type, flags, data, xenfs_fill_super); + return get_sb_single(fs_type, flags, data, xenfs_fill_super, mnt); } static struct file_system_type xenfs_type = { .owner = THIS_MODULE, .name = "xenfs", - .mount = xenfs_mount, + .get_sb = xenfs_get_sb, .kill_sb = kill_litter_super, }; diff --git a/trunk/fs/9p/vfs_super.c b/trunk/fs/9p/vfs_super.c index c55c614500ad..48d4215c60a8 100644 --- a/trunk/fs/9p/vfs_super.c +++ b/trunk/fs/9p/vfs_super.c @@ -68,7 +68,7 @@ static int v9fs_set_super(struct super_block *s, void *data) * v9fs_fill_super - populate superblock with info * @sb: superblock * @v9ses: session information - * @flags: flags propagated from v9fs_mount() + * @flags: flags propagated from v9fs_get_sb() * */ @@ -99,16 +99,18 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses, } /** - * v9fs_mount - mount a superblock + * v9fs_get_sb - mount a superblock * @fs_type: file system type * @flags: mount flags * @dev_name: device name that was mounted * @data: mount options + * @mnt: mountpoint record to be instantiated * */ -static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *data) +static int v9fs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, + struct vfsmount *mnt) { struct super_block *sb = NULL; struct inode *inode = NULL; @@ -122,7 +124,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags, v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL); if (!v9ses) - return ERR_PTR(-ENOMEM); + return -ENOMEM; fid = v9fs_session_init(v9ses, dev_name, data); if (IS_ERR(fid)) { @@ -184,15 +186,15 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags, v9fs_fid_add(root, fid); P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n"); - return dget(sb->s_root); + simple_set_mnt(mnt, sb); + return 0; clunk_fid: p9_client_clunk(fid); close_session: v9fs_session_close(v9ses); kfree(v9ses); - return ERR_PTR(retval); - + return retval; release_sb: /* * we will do the session_close and root dentry release @@ -202,7 +204,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags, */ p9_client_clunk(fid); deactivate_locked_super(sb); - return ERR_PTR(retval); + return retval; } /** @@ -298,7 +300,7 @@ static const struct super_operations v9fs_super_ops_dotl = { struct file_system_type v9fs_fs_type = { .name = "9p", - .mount = v9fs_mount, + .get_sb = v9fs_get_sb, .kill_sb = v9fs_kill_super, .owner = THIS_MODULE, .fs_flags = FS_RENAME_DOES_D_MOVE, diff --git a/trunk/fs/adfs/super.c b/trunk/fs/adfs/super.c index 959dbff2d42d..d9803f73236f 100644 --- a/trunk/fs/adfs/super.c +++ b/trunk/fs/adfs/super.c @@ -490,16 +490,17 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent) return -EINVAL; } -static struct dentry *adfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int adfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, adfs_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, adfs_fill_super, + mnt); } static struct file_system_type adfs_fs_type = { .owner = THIS_MODULE, .name = "adfs", - .mount = adfs_mount, + .get_sb = adfs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/affs/super.c b/trunk/fs/affs/super.c index 0cf7f4384cbd..fa4fbe1e238a 100644 --- a/trunk/fs/affs/super.c +++ b/trunk/fs/affs/super.c @@ -573,16 +573,17 @@ affs_statfs(struct dentry *dentry, struct kstatfs *buf) return 0; } -static struct dentry *affs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int affs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, affs_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, affs_fill_super, + mnt); } static struct file_system_type affs_fs_type = { .owner = THIS_MODULE, .name = "affs", - .mount = affs_mount, + .get_sb = affs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/afs/super.c b/trunk/fs/afs/super.c index 27201cffece4..eacf76d98ae0 100644 --- a/trunk/fs/afs/super.c +++ b/trunk/fs/afs/super.c @@ -29,8 +29,9 @@ #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ static void afs_i_init_once(void *foo); -static struct dentry *afs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data); +static int afs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, + void *data, struct vfsmount *mnt); static struct inode *afs_alloc_inode(struct super_block *sb); static void afs_put_super(struct super_block *sb); static void afs_destroy_inode(struct inode *inode); @@ -39,7 +40,7 @@ static int afs_statfs(struct dentry *dentry, struct kstatfs *buf); struct file_system_type afs_fs_type = { .owner = THIS_MODULE, .name = "afs", - .mount = afs_mount, + .get_sb = afs_get_sb, .kill_sb = kill_anon_super, .fs_flags = 0, }; @@ -358,8 +359,11 @@ static int afs_fill_super(struct super_block *sb, void *data) /* * get an AFS superblock */ -static struct dentry *afs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *options) +static int afs_get_sb(struct file_system_type *fs_type, + int flags, + const char *dev_name, + void *options, + struct vfsmount *mnt) { struct afs_mount_params params; struct super_block *sb; @@ -423,11 +427,12 @@ static struct dentry *afs_mount(struct file_system_type *fs_type, ASSERTCMP(sb->s_flags, &, MS_ACTIVE); } + simple_set_mnt(mnt, sb); afs_put_volume(params.volume); afs_put_cell(params.cell); kfree(new_opts); _leave(" = 0 [%p]", sb); - return dget(sb->s_root); + return 0; error: afs_put_volume(params.volume); @@ -435,7 +440,7 @@ static struct dentry *afs_mount(struct file_system_type *fs_type, key_put(params.key); kfree(new_opts); _leave(" = %d", ret); - return ERR_PTR(ret); + return ret; } /* diff --git a/trunk/fs/anon_inodes.c b/trunk/fs/anon_inodes.c index 57ce55b2564c..5365527ca43f 100644 --- a/trunk/fs/anon_inodes.c +++ b/trunk/fs/anon_inodes.c @@ -26,10 +26,12 @@ static struct vfsmount *anon_inode_mnt __read_mostly; static struct inode *anon_inode_inode; static const struct file_operations anon_inode_fops; -static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int anon_inodefs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, + struct vfsmount *mnt) { - return mount_pseudo(fs_type, "anon_inode:", NULL, ANON_INODE_FS_MAGIC); + return get_sb_pseudo(fs_type, "anon_inode:", NULL, ANON_INODE_FS_MAGIC, + mnt); } /* @@ -43,7 +45,7 @@ static char *anon_inodefs_dname(struct dentry *dentry, char *buffer, int buflen) static struct file_system_type anon_inode_fs_type = { .name = "anon_inodefs", - .mount = anon_inodefs_mount, + .get_sb = anon_inodefs_get_sb, .kill_sb = kill_anon_super, }; static const struct dentry_operations anon_inodefs_dentry_operations = { diff --git a/trunk/fs/autofs4/init.c b/trunk/fs/autofs4/init.c index c038727b4050..9722e4bd8957 100644 --- a/trunk/fs/autofs4/init.c +++ b/trunk/fs/autofs4/init.c @@ -14,16 +14,16 @@ #include #include "autofs_i.h" -static struct dentry *autofs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int autofs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_nodev(fs_type, flags, data, autofs4_fill_super); + return get_sb_nodev(fs_type, flags, data, autofs4_fill_super, mnt); } static struct file_system_type autofs_fs_type = { .owner = THIS_MODULE, .name = "autofs", - .mount = autofs_mount, + .get_sb = autofs_get_sb, .kill_sb = autofs4_kill_sb, }; diff --git a/trunk/fs/befs/linuxvfs.c b/trunk/fs/befs/linuxvfs.c index aa4e7c7ae3c6..dc39d2824885 100644 --- a/trunk/fs/befs/linuxvfs.c +++ b/trunk/fs/befs/linuxvfs.c @@ -913,17 +913,18 @@ befs_statfs(struct dentry *dentry, struct kstatfs *buf) return 0; } -static struct dentry * -befs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, - void *data) +static int +befs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, + void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, befs_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, befs_fill_super, + mnt); } static struct file_system_type befs_fs_type = { .owner = THIS_MODULE, .name = "befs", - .mount = befs_mount, + .get_sb = befs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/bfs/inode.c b/trunk/fs/bfs/inode.c index 76db6d7d49bb..883e77acd5a8 100644 --- a/trunk/fs/bfs/inode.c +++ b/trunk/fs/bfs/inode.c @@ -450,16 +450,16 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) return ret; } -static struct dentry *bfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int bfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, bfs_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, bfs_fill_super, mnt); } static struct file_system_type bfs_fs_type = { .owner = THIS_MODULE, .name = "bfs", - .mount = bfs_mount, + .get_sb = bfs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/binfmt_misc.c b/trunk/fs/binfmt_misc.c index 1befe2ec8186..29990f0eee0c 100644 --- a/trunk/fs/binfmt_misc.c +++ b/trunk/fs/binfmt_misc.c @@ -706,10 +706,10 @@ static int bm_fill_super(struct super_block * sb, void * data, int silent) return err; } -static struct dentry *bm_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int bm_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_single(fs_type, flags, data, bm_fill_super); + return get_sb_single(fs_type, flags, data, bm_fill_super, mnt); } static struct linux_binfmt misc_format = { @@ -720,7 +720,7 @@ static struct linux_binfmt misc_format = { static struct file_system_type bm_fs_type = { .owner = THIS_MODULE, .name = "binfmt_misc", - .mount = bm_mount, + .get_sb = bm_get_sb, .kill_sb = kill_litter_super, }; diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index 06e8ff12b97c..dea3b628a6ce 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -464,15 +464,15 @@ static const struct super_operations bdev_sops = { .evict_inode = bdev_evict_inode, }; -static struct dentry *bd_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int bd_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_pseudo(fs_type, "bdev:", &bdev_sops, 0x62646576); + return get_sb_pseudo(fs_type, "bdev:", &bdev_sops, 0x62646576, mnt); } static struct file_system_type bd_type = { .name = "bdev", - .mount = bd_mount, + .get_sb = bd_get_sb, .kill_sb = kill_anon_super, }; diff --git a/trunk/fs/btrfs/super.c b/trunk/fs/btrfs/super.c index ebe46c628748..144f8a5730f5 100644 --- a/trunk/fs/btrfs/super.c +++ b/trunk/fs/btrfs/super.c @@ -560,8 +560,8 @@ static int btrfs_test_super(struct super_block *s, void *data) * Note: This is based on get_sb_bdev from fs/super.c with a few additions * for multiple device setup. Make sure to keep it in sync. */ -static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *data) +static int btrfs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, struct vfsmount *mnt) { struct block_device *bdev = NULL; struct super_block *s; @@ -580,7 +580,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, &subvol_name, &subvol_objectid, &fs_devices); if (error) - return ERR_PTR(error); + return error; error = btrfs_scan_one_device(dev_name, mode, fs_type, &fs_devices); if (error) @@ -656,8 +656,11 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, root = new_root; } + mnt->mnt_sb = s; + mnt->mnt_root = root; + kfree(subvol_name); - return root; + return 0; error_s: error = PTR_ERR(s); @@ -666,7 +669,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, error_free_subvol_name: kfree(subvol_name); error: - return ERR_PTR(error); + return error; } static int btrfs_remount(struct super_block *sb, int *flags, char *data) @@ -743,7 +746,7 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) static struct file_system_type btrfs_fs_type = { .owner = THIS_MODULE, .name = "btrfs", - .mount = btrfs_mount, + .get_sb = btrfs_get_sb, .kill_sb = kill_anon_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/ceph/super.c b/trunk/fs/ceph/super.c index 08b460ae0539..d6e0e0421891 100644 --- a/trunk/fs/ceph/super.c +++ b/trunk/fs/ceph/super.c @@ -635,7 +635,7 @@ static struct dentry *open_root_dentry(struct ceph_fs_client *fsc, /* * mount: join the ceph cluster, and open root directory. */ -static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc, +static int ceph_mount(struct ceph_fs_client *fsc, struct vfsmount *mnt, const char *path) { int err; @@ -678,14 +678,16 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc, } } + mnt->mnt_root = root; + mnt->mnt_sb = fsc->sb; + fsc->mount_state = CEPH_MOUNT_MOUNTED; dout("mount success\n"); - mutex_unlock(&fsc->client->mount_mutex); - return root; + err = 0; out: mutex_unlock(&fsc->client->mount_mutex); - return ERR_PTR(err); + return err; fail: if (first) { @@ -775,45 +777,41 @@ static int ceph_register_bdi(struct super_block *sb, return err; } -static struct dentry *ceph_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int ceph_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, + struct vfsmount *mnt) { struct super_block *sb; struct ceph_fs_client *fsc; - struct dentry *res; int err; int (*compare_super)(struct super_block *, void *) = ceph_compare_super; const char *path = NULL; struct ceph_mount_options *fsopt = NULL; struct ceph_options *opt = NULL; - dout("ceph_mount\n"); + dout("ceph_get_sb\n"); err = parse_mount_options(&fsopt, &opt, flags, data, dev_name, &path); - if (err < 0) { - res = ERR_PTR(err); + if (err < 0) goto out_final; - } /* create client (which we may/may not use) */ fsc = create_fs_client(fsopt, opt); if (IS_ERR(fsc)) { - res = ERR_CAST(fsc); + err = PTR_ERR(fsc); kfree(fsopt); kfree(opt); goto out_final; } err = ceph_mdsc_init(fsc); - if (err < 0) { - res = ERR_PTR(err); + if (err < 0) goto out; - } if (ceph_test_opt(fsc->client, NOSHARE)) compare_super = NULL; sb = sget(fs_type, compare_super, ceph_set_super, fsc); if (IS_ERR(sb)) { - res = ERR_CAST(sb); + err = PTR_ERR(sb); goto out; } @@ -825,18 +823,16 @@ static struct dentry *ceph_mount(struct file_system_type *fs_type, } else { dout("get_sb using new client %p\n", fsc); err = ceph_register_bdi(sb, fsc); - if (err < 0) { - res = ERR_PTR(err); + if (err < 0) goto out_splat; - } } - res = ceph_real_mount(fsc, path); - if (IS_ERR(res)) + err = ceph_mount(fsc, mnt, path); + if (err < 0) goto out_splat; - dout("root %p inode %p ino %llx.%llx\n", res, - res->d_inode, ceph_vinop(res->d_inode)); - return res; + dout("root %p inode %p ino %llx.%llx\n", mnt->mnt_root, + mnt->mnt_root->d_inode, ceph_vinop(mnt->mnt_root->d_inode)); + return 0; out_splat: ceph_mdsc_close_sessions(fsc->mdsc); @@ -847,8 +843,8 @@ static struct dentry *ceph_mount(struct file_system_type *fs_type, ceph_mdsc_destroy(fsc); destroy_fs_client(fsc); out_final: - dout("ceph_mount fail %ld\n", PTR_ERR(res)); - return res; + dout("ceph_get_sb fail %d\n", err); + return err; } static void ceph_kill_sb(struct super_block *s) @@ -864,7 +860,7 @@ static void ceph_kill_sb(struct super_block *s) static struct file_system_type ceph_fs_type = { .owner = THIS_MODULE, .name = "ceph", - .mount = ceph_mount, + .get_sb = ceph_get_sb, .kill_sb = ceph_kill_sb, .fs_flags = FS_RENAME_DOES_D_MOVE, }; diff --git a/trunk/fs/cifs/Kconfig b/trunk/fs/cifs/Kconfig index 0ed213970ced..917b7d449bb2 100644 --- a/trunk/fs/cifs/Kconfig +++ b/trunk/fs/cifs/Kconfig @@ -2,9 +2,6 @@ config CIFS tristate "CIFS support (advanced network filesystem, SMBFS successor)" depends on INET select NLS - select CRYPTO - select CRYPTO_MD5 - select CRYPTO_ARC4 help This is the client VFS module for the Common Internet File System (CIFS) protocol which is the successor to the Server Message Block diff --git a/trunk/fs/cifs/cifsencrypt.c b/trunk/fs/cifs/cifsencrypt.c index f856732161ab..7ac0056294cf 100644 --- a/trunk/fs/cifs/cifsencrypt.c +++ b/trunk/fs/cifs/cifsencrypt.c @@ -43,32 +43,18 @@ extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24); static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, - struct TCP_Server_Info *server, char *signature) + const struct session_key *key, char *signature) { - int rc; + struct MD5Context context; - if (cifs_pdu == NULL || signature == NULL || server == NULL) + if ((cifs_pdu == NULL) || (signature == NULL) || (key == NULL)) return -EINVAL; - if (!server->secmech.sdescmd5) { - cERROR(1, "%s: Can't generate signature\n", __func__); - return -1; - } - - rc = crypto_shash_init(&server->secmech.sdescmd5->shash); - if (rc) { - cERROR(1, "%s: Oould not init md5\n", __func__); - return rc; - } - - crypto_shash_update(&server->secmech.sdescmd5->shash, - server->session_key.response, server->session_key.len); - - crypto_shash_update(&server->secmech.sdescmd5->shash, - cifs_pdu->Protocol, cifs_pdu->smb_buf_length); - - rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature); + cifs_MD5_init(&context); + cifs_MD5_update(&context, (char *)&key->data, key->len); + cifs_MD5_update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length); + cifs_MD5_final(signature, &context); return 0; } @@ -93,7 +79,8 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, server->sequence_number++; spin_unlock(&GlobalMid_Lock); - rc = cifs_calculate_signature(cifs_pdu, server, smb_signature); + rc = cifs_calculate_signature(cifs_pdu, &server->session_key, + smb_signature); if (rc) memset(cifs_pdu->Signature.SecuritySignature, 0, 8); else @@ -103,28 +90,16 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, } static int cifs_calc_signature2(const struct kvec *iov, int n_vec, - struct TCP_Server_Info *server, char *signature) + const struct session_key *key, char *signature) { + struct MD5Context context; int i; - int rc; - if (iov == NULL || signature == NULL || server == NULL) + if ((iov == NULL) || (signature == NULL) || (key == NULL)) return -EINVAL; - if (!server->secmech.sdescmd5) { - cERROR(1, "%s: Can't generate signature\n", __func__); - return -1; - } - - rc = crypto_shash_init(&server->secmech.sdescmd5->shash); - if (rc) { - cERROR(1, "%s: Oould not init md5\n", __func__); - return rc; - } - - crypto_shash_update(&server->secmech.sdescmd5->shash, - server->session_key.response, server->session_key.len); - + cifs_MD5_init(&context); + cifs_MD5_update(&context, (char *)&key->data, key->len); for (i = 0; i < n_vec; i++) { if (iov[i].iov_len == 0) continue; @@ -137,18 +112,18 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec, if (i == 0) { if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ break; /* nothing to sign or corrupt header */ - crypto_shash_update(&server->secmech.sdescmd5->shash, - iov[i].iov_base + 4, iov[i].iov_len - 4); + cifs_MD5_update(&context, iov[0].iov_base+4, + iov[0].iov_len-4); } else - crypto_shash_update(&server->secmech.sdescmd5->shash, - iov[i].iov_base, iov[i].iov_len); + cifs_MD5_update(&context, iov[i].iov_base, iov[i].iov_len); } - rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature); + cifs_MD5_final(signature, &context); - return rc; + return 0; } + int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, __u32 *pexpected_response_sequence_number) { @@ -171,7 +146,8 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, server->sequence_number++; spin_unlock(&GlobalMid_Lock); - rc = cifs_calc_signature2(iov, n_vec, server, smb_signature); + rc = cifs_calc_signature2(iov, n_vec, &server->session_key, + smb_signature); if (rc) memset(cifs_pdu->Signature.SecuritySignature, 0, 8); else @@ -181,14 +157,14 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, } int cifs_verify_signature(struct smb_hdr *cifs_pdu, - struct TCP_Server_Info *server, + const struct session_key *session_key, __u32 expected_sequence_number) { unsigned int rc; char server_response_sig[8]; char what_we_think_sig_should_be[20]; - if (cifs_pdu == NULL || server == NULL) + if (cifs_pdu == NULL || session_key == NULL) return -EINVAL; if (cifs_pdu->Command == SMB_COM_NEGOTIATE) @@ -217,7 +193,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, cpu_to_le32(expected_sequence_number); cifs_pdu->Signature.Sequence.Reserved = 0; - rc = cifs_calculate_signature(cifs_pdu, server, + rc = cifs_calculate_signature(cifs_pdu, session_key, what_we_think_sig_should_be); if (rc) @@ -233,28 +209,18 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, } -/* first calculate 24 bytes ntlm response and then 16 byte session key */ -int setup_ntlm_response(struct cifsSesInfo *ses) +/* We fill in key by putting in 40 byte array which was allocated by caller */ +int cifs_calculate_session_key(struct session_key *key, const char *rn, + const char *password) { - unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE; - char temp_key[CIFS_SESS_KEY_SIZE]; - - if (!ses) + char temp_key[16]; + if ((key == NULL) || (rn == NULL)) return -EINVAL; - ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL); - if (!ses->auth_key.response) { - cERROR(1, "NTLM can't allocate (%u bytes) memory", temp_len); - return -ENOMEM; - } - ses->auth_key.len = temp_len; - - SMBNTencrypt(ses->password, ses->server->cryptkey, - ses->auth_key.response + CIFS_SESS_KEY_SIZE); - - E_md4hash(ses->password, temp_key); - mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE); - + E_md4hash(password, temp_key); + mdfour(key->data.ntlm, temp_key, 16); + memcpy(key->data.ntlm+16, rn, CIFS_SESS_KEY_SIZE); + key->len = 40; return 0; } @@ -328,15 +294,15 @@ build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp) * two times the unicode length of a server name + * size of a timestamp (which is 8 bytes). */ - ses->auth_key.len = size + 2 * (2 * dlen) + 2 * (2 * wlen) + 8; - ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL); - if (!ses->auth_key.response) { - ses->auth_key.len = 0; + ses->tilen = size + 2 * (2 * dlen) + 2 * (2 * wlen) + 8; + ses->tiblob = kzalloc(ses->tilen, GFP_KERNEL); + if (!ses->tiblob) { + ses->tilen = 0; cERROR(1, "Challenge target info allocation failure"); return -ENOMEM; } - blobptr = ses->auth_key.response; + blobptr = ses->tiblob; attrptr = (struct ntlmssp2_name *) blobptr; attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME); @@ -391,7 +357,7 @@ build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp) * about target string i.e. for some, just user name might suffice. */ static int -find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp) +find_domain_name(struct cifsSesInfo *ses) { unsigned int attrsize; unsigned int type; @@ -400,11 +366,11 @@ find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp) unsigned char *blobend; struct ntlmssp2_name *attrptr; - if (!ses->auth_key.len || !ses->auth_key.response) + if (!ses->tilen || !ses->tiblob) return 0; - blobptr = ses->auth_key.response; - blobend = blobptr + ses->auth_key.len; + blobptr = ses->tiblob; + blobend = ses->tiblob + ses->tilen; while (blobptr + onesize < blobend) { attrptr = (struct ntlmssp2_name *) blobptr; @@ -420,13 +386,16 @@ find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp) if (!attrsize) break; if (!ses->domainName) { + struct nls_table *default_nls; ses->domainName = kmalloc(attrsize + 1, GFP_KERNEL); if (!ses->domainName) return -ENOMEM; + default_nls = load_nls_default(); cifs_from_ucs2(ses->domainName, (__le16 *)blobptr, attrsize, attrsize, - nls_cp, false); + default_nls, false); + unload_nls(default_nls); break; } } @@ -436,136 +405,82 @@ find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp) return 0; } -static int calc_ntlmv2_hash(struct cifsSesInfo *ses, char *ntlmv2_hash, +static int calc_ntlmv2_hash(struct cifsSesInfo *ses, const struct nls_table *nls_cp) { int rc = 0; int len; - char nt_hash[CIFS_NTHASH_SIZE]; + char nt_hash[16]; + struct HMACMD5Context *pctxt; wchar_t *user; wchar_t *domain; - wchar_t *server; - if (!ses->server->secmech.sdeschmacmd5) { - cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); - return -1; - } + pctxt = kmalloc(sizeof(struct HMACMD5Context), GFP_KERNEL); + + if (pctxt == NULL) + return -ENOMEM; /* calculate md4 hash of password */ E_md4hash(ses->password, nt_hash); - crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash, - CIFS_NTHASH_SIZE); - - rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); - if (rc) { - cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5\n"); - return rc; - } + /* convert Domainname to unicode and uppercase */ + hmac_md5_init_limK_to_64(nt_hash, 16, pctxt); /* convert ses->userName to unicode and uppercase */ len = strlen(ses->userName); user = kmalloc(2 + (len * 2), GFP_KERNEL); - if (user == NULL) { - cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n"); - rc = -ENOMEM; + if (user == NULL) goto calc_exit_2; - } len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp); UniStrupr(user); - - crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, - (char *)user, 2 * len); + hmac_md5_update((char *)user, 2*len, pctxt); /* convert ses->domainName to unicode and uppercase */ if (ses->domainName) { len = strlen(ses->domainName); domain = kmalloc(2 + (len * 2), GFP_KERNEL); - if (domain == NULL) { - cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure"); - rc = -ENOMEM; + if (domain == NULL) goto calc_exit_1; - } len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len, nls_cp); - crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, - (char *)domain, 2 * len); - kfree(domain); - } else if (ses->serverName) { - len = strlen(ses->serverName); - - server = kmalloc(2 + (len * 2), GFP_KERNEL); - if (server == NULL) { - cERROR(1, "calc_ntlmv2_hash: server mem alloc failure"); - rc = -ENOMEM; - goto calc_exit_1; - } - len = cifs_strtoUCS((__le16 *)server, ses->serverName, len, - nls_cp); - crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, - (char *)server, 2 * len); - kfree(server); - } + /* the following line was removed since it didn't work well + with lower cased domain name that passed as an option. + Maybe converting the domain name earlier makes sense */ + /* UniStrupr(domain); */ - rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, - ntlmv2_hash); + hmac_md5_update((char *)domain, 2*len, pctxt); + kfree(domain); + } calc_exit_1: kfree(user); calc_exit_2: - return rc; -} - -static int -CalcNTLMv2_response(const struct cifsSesInfo *ses, char *ntlmv2_hash) -{ - int rc; - unsigned int offset = CIFS_SESS_KEY_SIZE + 8; - - if (!ses->server->secmech.sdeschmacmd5) { - cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); - return -1; - } - - crypto_shash_setkey(ses->server->secmech.hmacmd5, - ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); - - rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); - if (rc) { - cERROR(1, "CalcNTLMv2_response: could not init hmacmd5"); - return rc; - } - - if (ses->server->secType == RawNTLMSSP) - memcpy(ses->auth_key.response + offset, - ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); - else - memcpy(ses->auth_key.response + offset, - ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); - crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, - ses->auth_key.response + offset, ses->auth_key.len - offset); - - rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, - ses->auth_key.response + CIFS_SESS_KEY_SIZE); + /* BB FIXME what about bytes 24 through 40 of the signing key? + compare with the NTLM example */ + hmac_md5_final(ses->ntlmv2_hash, pctxt); + kfree(pctxt); return rc; } - int -setup_ntlmv2_rsp(struct cifsSesInfo *ses, const struct nls_table *nls_cp) +setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf, + const struct nls_table *nls_cp) { int rc; - int baselen; - unsigned int tilen; - struct ntlmv2_resp *buf; - char ntlmv2_hash[16]; - unsigned char *tiblob = NULL; /* target info blob */ + struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf; + struct HMACMD5Context context; + + buf->blob_signature = cpu_to_le32(0x00000101); + buf->reserved = 0; + buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); + get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); + buf->reserved2 = 0; if (ses->server->secType == RawNTLMSSP) { if (!ses->domainName) { - rc = find_domain_name(ses, nls_cp); + rc = find_domain_name(ses); if (rc) { cERROR(1, "error %d finding domain name", rc); goto setup_ntlmv2_rsp_ret; @@ -575,179 +490,51 @@ setup_ntlmv2_rsp(struct cifsSesInfo *ses, const struct nls_table *nls_cp) rc = build_avpair_blob(ses, nls_cp); if (rc) { cERROR(1, "error %d building av pair blob", rc); - goto setup_ntlmv2_rsp_ret; + return rc; } } - baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp); - tilen = ses->auth_key.len; - tiblob = ses->auth_key.response; - - ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL); - if (!ses->auth_key.response) { - rc = ENOMEM; - ses->auth_key.len = 0; - cERROR(1, "%s: Can't allocate auth blob", __func__); - goto setup_ntlmv2_rsp_ret; - } - ses->auth_key.len += baselen; - - buf = (struct ntlmv2_resp *) - (ses->auth_key.response + CIFS_SESS_KEY_SIZE); - buf->blob_signature = cpu_to_le32(0x00000101); - buf->reserved = 0; - buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); - get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); - buf->reserved2 = 0; - - memcpy(ses->auth_key.response + baselen, tiblob, tilen); - - /* calculate ntlmv2_hash */ - rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp); + /* calculate buf->ntlmv2_hash */ + rc = calc_ntlmv2_hash(ses, nls_cp); if (rc) { cERROR(1, "could not get v2 hash rc %d", rc); goto setup_ntlmv2_rsp_ret; } - - /* calculate first part of the client response (CR1) */ - rc = CalcNTLMv2_response(ses, ntlmv2_hash); - if (rc) { - cERROR(1, "Could not calculate CR1 rc: %d", rc); - goto setup_ntlmv2_rsp_ret; - } + CalcNTLMv2_response(ses, resp_buf); /* now calculate the session key for NTLMv2 */ - crypto_shash_setkey(ses->server->secmech.hmacmd5, - ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); - - rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); - if (rc) { - cERROR(1, "%s: Could not init hmacmd5\n", __func__); - goto setup_ntlmv2_rsp_ret; - } + hmac_md5_init_limK_to_64(ses->ntlmv2_hash, 16, &context); + hmac_md5_update(resp_buf, 16, &context); + hmac_md5_final(ses->auth_key.data.ntlmv2.key, &context); - crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, - ses->auth_key.response + CIFS_SESS_KEY_SIZE, - CIFS_HMAC_MD5_HASH_SIZE); + memcpy(&ses->auth_key.data.ntlmv2.resp, resp_buf, + sizeof(struct ntlmv2_resp)); + ses->auth_key.len = 16 + sizeof(struct ntlmv2_resp); - rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, - ses->auth_key.response); + return 0; setup_ntlmv2_rsp_ret: - kfree(tiblob); + kfree(ses->tiblob); + ses->tiblob = NULL; + ses->tilen = 0; return rc; } -int -calc_seckey(struct cifsSesInfo *ses) +void CalcNTLMv2_response(const struct cifsSesInfo *ses, + char *v2_session_response) { - int rc; - struct crypto_blkcipher *tfm_arc4; - struct scatterlist sgin, sgout; - struct blkcipher_desc desc; - unsigned char sec_key[CIFS_SESS_KEY_SIZE]; /* a nonce */ - - get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE); - - tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); - if (!tfm_arc4 || IS_ERR(tfm_arc4)) { - cERROR(1, "could not allocate crypto API arc4\n"); - return PTR_ERR(tfm_arc4); - } + struct HMACMD5Context context; + /* rest of v2 struct already generated */ + memcpy(v2_session_response + 8, ses->cryptKey, 8); + hmac_md5_init_limK_to_64(ses->ntlmv2_hash, 16, &context); - desc.tfm = tfm_arc4; + hmac_md5_update(v2_session_response+8, + sizeof(struct ntlmv2_resp) - 8, &context); - crypto_blkcipher_setkey(tfm_arc4, ses->auth_key.response, - CIFS_SESS_KEY_SIZE); + if (ses->tilen) + hmac_md5_update(ses->tiblob, ses->tilen, &context); - sg_init_one(&sgin, sec_key, CIFS_SESS_KEY_SIZE); - sg_init_one(&sgout, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE); - - rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, CIFS_CPHTXT_SIZE); - if (rc) { - cERROR(1, "could not encrypt session key rc: %d\n", rc); - crypto_free_blkcipher(tfm_arc4); - return rc; - } - - /* make secondary_key/nonce as session key */ - memcpy(ses->auth_key.response, sec_key, CIFS_SESS_KEY_SIZE); - /* and make len as that of session key only */ - ses->auth_key.len = CIFS_SESS_KEY_SIZE; - - crypto_free_blkcipher(tfm_arc4); - - return 0; -} - -void -cifs_crypto_shash_release(struct TCP_Server_Info *server) -{ - if (server->secmech.md5) - crypto_free_shash(server->secmech.md5); - - if (server->secmech.hmacmd5) - crypto_free_shash(server->secmech.hmacmd5); - - kfree(server->secmech.sdeschmacmd5); - - kfree(server->secmech.sdescmd5); -} - -int -cifs_crypto_shash_allocate(struct TCP_Server_Info *server) -{ - int rc; - unsigned int size; - - server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0); - if (!server->secmech.hmacmd5 || - IS_ERR(server->secmech.hmacmd5)) { - cERROR(1, "could not allocate crypto hmacmd5\n"); - return PTR_ERR(server->secmech.hmacmd5); - } - - server->secmech.md5 = crypto_alloc_shash("md5", 0, 0); - if (!server->secmech.md5 || IS_ERR(server->secmech.md5)) { - cERROR(1, "could not allocate crypto md5\n"); - rc = PTR_ERR(server->secmech.md5); - goto crypto_allocate_md5_fail; - } - - size = sizeof(struct shash_desc) + - crypto_shash_descsize(server->secmech.hmacmd5); - server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL); - if (!server->secmech.sdeschmacmd5) { - cERROR(1, "cifs_crypto_shash_allocate: can't alloc hmacmd5\n"); - rc = -ENOMEM; - goto crypto_allocate_hmacmd5_sdesc_fail; - } - server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5; - server->secmech.sdeschmacmd5->shash.flags = 0x0; - - - size = sizeof(struct shash_desc) + - crypto_shash_descsize(server->secmech.md5); - server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL); - if (!server->secmech.sdescmd5) { - cERROR(1, "cifs_crypto_shash_allocate: can't alloc md5\n"); - rc = -ENOMEM; - goto crypto_allocate_md5_sdesc_fail; - } - server->secmech.sdescmd5->shash.tfm = server->secmech.md5; - server->secmech.sdescmd5->shash.flags = 0x0; - - return 0; - -crypto_allocate_md5_sdesc_fail: - kfree(server->secmech.sdeschmacmd5); - -crypto_allocate_hmacmd5_sdesc_fail: - crypto_free_shash(server->secmech.md5); - -crypto_allocate_md5_fail: - crypto_free_shash(server->secmech.hmacmd5); - - return rc; + hmac_md5_final(v2_session_response, &context); +/* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */ } diff --git a/trunk/fs/cifs/cifsfs.c b/trunk/fs/cifs/cifsfs.c index 75c4eaa79588..34371637f210 100644 --- a/trunk/fs/cifs/cifsfs.c +++ b/trunk/fs/cifs/cifsfs.c @@ -318,6 +318,7 @@ cifs_alloc_inode(struct super_block *sb) return NULL; cifs_inode->cifsAttrs = 0x20; /* default */ cifs_inode->time = 0; + cifs_inode->write_behind_rc = 0; /* Until the file is open and we have gotten oplock info back from the server, can not assume caching of file data or metadata */ @@ -544,9 +545,9 @@ static const struct super_operations cifs_super_ops = { #endif }; -static struct dentry * -cifs_do_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int +cifs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { int rc; struct super_block *sb; @@ -556,17 +557,18 @@ cifs_do_mount(struct file_system_type *fs_type, cFYI(1, "Devname: %s flags: %d ", dev_name, flags); if (IS_ERR(sb)) - return ERR_CAST(sb); + return PTR_ERR(sb); sb->s_flags = flags; rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0); if (rc) { deactivate_locked_super(sb); - return ERR_PTR(rc); + return rc; } sb->s_flags |= MS_ACTIVE; - return dget(sb->s_root); + simple_set_mnt(mnt, sb); + return 0; } static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, @@ -632,7 +634,7 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) struct file_system_type cifs_fs_type = { .owner = THIS_MODULE, .name = "cifs", - .mount = cifs_do_mount, + .get_sb = cifs_get_sb, .kill_sb = kill_anon_super, /* .fs_flags */ }; diff --git a/trunk/fs/cifs/cifsfs.h b/trunk/fs/cifs/cifsfs.h index 897b2b2b28b5..f35795a16b42 100644 --- a/trunk/fs/cifs/cifsfs.h +++ b/trunk/fs/cifs/cifsfs.h @@ -112,5 +112,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); extern const struct export_operations cifs_export_ops; #endif /* EXPERIMENTAL */ -#define CIFS_VERSION "1.68" +#define CIFS_VERSION "1.67" #endif /* _CIFSFS_H */ diff --git a/trunk/fs/cifs/cifsglob.h b/trunk/fs/cifs/cifsglob.h index f259e4d7612d..3365e77f6f24 100644 --- a/trunk/fs/cifs/cifsglob.h +++ b/trunk/fs/cifs/cifsglob.h @@ -25,9 +25,6 @@ #include #include "cifs_fs_sb.h" #include "cifsacl.h" -#include -#include - /* * The sizes of various internal tables and strings */ @@ -77,7 +74,7 @@ * CIFS vfs client Status information (based on what we know.) */ -/* associated with each tcp and smb session */ + /* associated with each tcp and smb session */ enum statusEnum { CifsNew = 0, CifsGood, @@ -102,29 +99,14 @@ enum protocolEnum { struct session_key { unsigned int len; - char *response; -}; - -/* crypto security descriptor definition */ -struct sdesc { - struct shash_desc shash; - char ctx[]; -}; - -/* crypto hashing related structure/fields, not specific to a sec mech */ -struct cifs_secmech { - struct crypto_shash *hmacmd5; /* hmac-md5 hash function */ - struct crypto_shash *md5; /* md5 hash function */ - struct sdesc *sdeschmacmd5; /* ctxt to generate ntlmv2 hash, CR1 */ - struct sdesc *sdescmd5; /* ctxt to generate cifs/smb signature */ -}; - -/* per smb session structure/fields */ -struct ntlmssp_auth { - __u32 client_flags; /* sent by client in type 1 ntlmsssp exchange */ - __u32 server_flags; /* sent by server in type 2 ntlmssp exchange */ - unsigned char ciphertext[CIFS_CPHTXT_SIZE]; /* sent to server */ - char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlmssp */ + union { + char ntlm[CIFS_SESS_KEY_SIZE + 16]; + char krb5[CIFS_SESS_KEY_SIZE + 16]; /* BB: length correct? */ + struct { + char key[16]; + struct ntlmv2_resp resp; + } ntlmv2; + } data; }; struct cifs_cred { @@ -197,14 +179,12 @@ struct TCP_Server_Info { int capabilities; /* allow selective disabling of caps by smb sess */ int timeAdj; /* Adjust for difference in server time zone in sec */ __u16 CurrentMid; /* multiplex id - rotating counter */ - char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlm, ntlmv2 etc */ /* 16th byte of RFC1001 workstation name is always null */ char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; __u32 sequence_number; /* needed for CIFS PDU signature */ struct session_key session_key; unsigned long lstrp; /* when we got last response from this server */ u16 dialect; /* dialect index that server chose */ - struct cifs_secmech secmech; /* crypto sec mech functs, descriptors */ /* extended security flavors that server supports */ bool sec_kerberos; /* supports plain Kerberos */ bool sec_mskerberos; /* supports legacy MS Kerberos */ @@ -242,8 +222,11 @@ struct cifsSesInfo { char userName[MAX_USERNAME_SIZE + 1]; char *domainName; char *password; + char cryptKey[CIFS_CRYPTO_KEY_SIZE]; struct session_key auth_key; - struct ntlmssp_auth *ntlmssp; /* ciphertext, flags, server challenge */ + char ntlmv2_hash[16]; + unsigned int tilen; /* length of the target info blob */ + unsigned char *tiblob; /* target info blob in challenge response */ bool need_reconnect:1; /* connection reset, uid now invalid */ }; /* no more than one of the following three session flags may be set */ @@ -412,19 +395,16 @@ struct cifsFileInfo { struct list_head llist; /* list of byte range locks we have. */ bool invalidHandle:1; /* file closed via session abend */ bool oplock_break_cancelled:1; - int count; /* refcount protected by cifs_file_list_lock */ + atomic_t count; /* reference count */ struct mutex fh_mutex; /* prevents reopen race after dead ses*/ struct cifs_search_info srch_inf; struct work_struct oplock_break; /* work for oplock breaks */ }; -/* - * Take a reference on the file private data. Must be called with - * cifs_file_list_lock held. - */ +/* Take a reference on the file private data */ static inline void cifsFileInfo_get(struct cifsFileInfo *cifs_file) { - ++cifs_file->count; + atomic_inc(&cifs_file->count); } void cifsFileInfo_put(struct cifsFileInfo *cifs_file); @@ -437,6 +417,7 @@ struct cifsInodeInfo { struct list_head lockList; /* BB add in lists for dirty pages i.e. write caching info for oplock */ struct list_head openFileList; + int write_behind_rc; __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */ unsigned long time; /* jiffies of last update/check of inode */ bool clientCanCacheRead:1; /* read oplock */ @@ -687,7 +668,7 @@ require use of the stronger protocol */ * GlobalMid_Lock protects: * list operations on pending_mid_q and oplockQ * updates to XID counters, multiplex id and SMB sequence numbers - * cifs_file_list_lock protects: + * GlobalSMBSesLock protects: * list operations on tcp and SMB session lists and tCon lists * f_owner.lock protects certain per file struct operations * mapping->page_lock protects certain per page operations diff --git a/trunk/fs/cifs/cifspdu.h b/trunk/fs/cifs/cifspdu.h index de36b09763a8..b0f4b5656d4c 100644 --- a/trunk/fs/cifs/cifspdu.h +++ b/trunk/fs/cifs/cifspdu.h @@ -130,21 +130,10 @@ */ #define CIFS_CRYPTO_KEY_SIZE (8) -/* - * Size of the ntlm client response - */ -#define CIFS_AUTH_RESP_SIZE (24) - /* * Size of the session key (crypto key encrypted with the password */ -#define CIFS_SESS_KEY_SIZE (16) - -#define CIFS_CLIENT_CHALLENGE_SIZE (8) -#define CIFS_SERVER_CHALLENGE_SIZE (8) -#define CIFS_HMAC_MD5_HASH_SIZE (16) -#define CIFS_CPHTXT_SIZE (16) -#define CIFS_NTHASH_SIZE (16) +#define CIFS_SESS_KEY_SIZE (24) /* * Maximum user name length diff --git a/trunk/fs/cifs/cifsproto.h b/trunk/fs/cifs/cifsproto.h index edb6d90efdf2..e593c40ba7ba 100644 --- a/trunk/fs/cifs/cifsproto.h +++ b/trunk/fs/cifs/cifsproto.h @@ -362,15 +362,13 @@ extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *); extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, __u32 *); extern int cifs_verify_signature(struct smb_hdr *, - struct TCP_Server_Info *server, + const struct session_key *session_key, __u32 expected_sequence_number); -extern void SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *); -extern int setup_ntlm_response(struct cifsSesInfo *); -extern int setup_ntlmv2_rsp(struct cifsSesInfo *, const struct nls_table *); -extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); -extern void cifs_crypto_shash_release(struct TCP_Server_Info *); -extern int calc_seckey(struct cifsSesInfo *); - +extern int cifs_calculate_session_key(struct session_key *key, const char *rn, + const char *pass); +extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *); +extern int setup_ntlmv2_rsp(struct cifsSesInfo *, char *, + const struct nls_table *); #ifdef CONFIG_CIFS_WEAK_PW_HASH extern void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt, char *lnm_session_key); diff --git a/trunk/fs/cifs/cifssmb.c b/trunk/fs/cifs/cifssmb.c index 2f2632b6df5a..e98f1f317b15 100644 --- a/trunk/fs/cifs/cifssmb.c +++ b/trunk/fs/cifs/cifssmb.c @@ -503,7 +503,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) if (rsp->EncryptionKeyLength == cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { - memcpy(ses->server->cryptkey, rsp->EncryptionKey, + memcpy(ses->cryptKey, rsp->EncryptionKey, CIFS_CRYPTO_KEY_SIZE); } else if (server->secMode & SECMODE_PW_ENCRYPT) { rc = -EIO; /* need cryptkey unless plain text */ @@ -574,7 +574,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); server->timeAdj *= 60; if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { - memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey, + memcpy(ses->cryptKey, pSMBr->u.EncryptionKey, CIFS_CRYPTO_KEY_SIZE); } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) && (pSMBr->EncryptionKeyLength == 0)) { diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index 9eb327defa1d..7e73176acb58 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -175,9 +175,6 @@ cifs_reconnect(struct TCP_Server_Info *server) } server->sequence_number = 0; server->session_estab = false; - kfree(server->session_key.response); - server->session_key.response = NULL; - server->session_key.len = 0; spin_lock(&GlobalMid_Lock); list_for_each(tmp, &server->pending_mid_q) { @@ -1067,7 +1064,7 @@ cifs_parse_mount_options(char *options, const char *devname, } i = cifs_convert_address((struct sockaddr *)&vol->srcaddr, value, strlen(value)); - if (i == 0) { + if (i < 0) { printk(KERN_WARNING "CIFS: Could not parse" " srcaddr: %s\n", value); @@ -1563,13 +1560,8 @@ cifs_put_tcp_session(struct TCP_Server_Info *server) server->tcpStatus = CifsExiting; spin_unlock(&GlobalMid_Lock); - cifs_crypto_shash_release(server); cifs_fscache_release_client_cookie(server); - kfree(server->session_key.response); - server->session_key.response = NULL; - server->session_key.len = 0; - task = xchg(&server->tsk, NULL); if (task) force_sig(SIGKILL, task); @@ -1622,16 +1614,10 @@ cifs_get_tcp_session(struct smb_vol *volume_info) goto out_err; } - rc = cifs_crypto_shash_allocate(tcp_ses); - if (rc) { - cERROR(1, "could not setup hash structures rc %d", rc); - goto out_err; - } - tcp_ses->hostname = extract_hostname(volume_info->UNC); if (IS_ERR(tcp_ses->hostname)) { rc = PTR_ERR(tcp_ses->hostname); - goto out_err_crypto_release; + goto out_err; } tcp_ses->noblocksnd = volume_info->noblocksnd; @@ -1675,7 +1661,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info) } if (rc < 0) { cERROR(1, "Error connecting to socket. Aborting operation"); - goto out_err_crypto_release; + goto out_err; } /* @@ -1689,7 +1675,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info) rc = PTR_ERR(tcp_ses->tsk); cERROR(1, "error %d create cifsd thread", rc); module_put(THIS_MODULE); - goto out_err_crypto_release; + goto out_err; } /* thread spawned, put it on the list */ @@ -1701,9 +1687,6 @@ cifs_get_tcp_session(struct smb_vol *volume_info) return tcp_ses; -out_err_crypto_release: - cifs_crypto_shash_release(tcp_ses); - out_err: if (tcp_ses) { if (!IS_ERR(tcp_ses->hostname)) @@ -1818,6 +1801,8 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) if (ses == NULL) goto get_ses_fail; + ses->tilen = 0; + ses->tiblob = NULL; /* new SMB session uses our server ref */ ses->server = server; if (server->addr.sockAddr6.sin6_family == AF_INET6) @@ -1838,9 +1823,10 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) goto get_ses_fail; } if (volume_info->domainname) { - ses->domainName = kstrdup(volume_info->domainname, GFP_KERNEL); - if (!ses->domainName) - goto get_ses_fail; + int len = strlen(volume_info->domainname); + ses->domainName = kmalloc(len + 1, GFP_KERNEL); + if (ses->domainName) + strcpy(ses->domainName, volume_info->domainname); } ses->cred_uid = volume_info->cred_uid; ses->linux_uid = volume_info->linux_uid; @@ -2999,13 +2985,13 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, #ifdef CONFIG_CIFS_WEAK_PW_HASH if ((global_secflags & CIFSSEC_MAY_LANMAN) && (ses->server->secType == LANMAN)) - calc_lanman_hash(tcon->password, ses->server->cryptkey, + calc_lanman_hash(tcon->password, ses->cryptKey, ses->server->secMode & SECMODE_PW_ENCRYPT ? true : false, bcc_ptr); else #endif /* CIFS_WEAK_PW_HASH */ - SMBNTencrypt(tcon->password, ses->server->cryptkey, bcc_ptr); + SMBNTencrypt(tcon->password, ses->cryptKey, bcc_ptr); bcc_ptr += CIFS_SESS_KEY_SIZE; if (ses->capabilities & CAP_UNICODE) { @@ -3192,11 +3178,10 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses, } else { mutex_lock(&ses->server->srv_mutex); if (!server->session_estab) { - server->session_key.response = ses->auth_key.response; + memcpy(&server->session_key.data, + &ses->auth_key.data, ses->auth_key.len); server->session_key.len = ses->auth_key.len; - server->sequence_number = 0x2; - server->session_estab = true; - ses->auth_key.response = NULL; + ses->server->session_estab = true; } mutex_unlock(&server->srv_mutex); @@ -3207,12 +3192,6 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses, spin_unlock(&GlobalMid_Lock); } - kfree(ses->auth_key.response); - ses->auth_key.response = NULL; - ses->auth_key.len = 0; - kfree(ses->ntlmssp); - ses->ntlmssp = NULL; - return rc; } diff --git a/trunk/fs/cifs/file.c b/trunk/fs/cifs/file.c index ae82159cf7fa..45af003865d2 100644 --- a/trunk/fs/cifs/file.c +++ b/trunk/fs/cifs/file.c @@ -131,7 +131,8 @@ static inline int cifs_open_inode_helper(struct inode *inode, /* BB no need to lock inode until after invalidate since namei code should already have it locked? */ rc = filemap_write_and_wait(inode->i_mapping); - mapping_set_error(inode->i_mapping, rc); + if (rc != 0) + pCifsInode->write_behind_rc = rc; } cFYI(1, "invalidating remote inode since open detected it " "changed"); @@ -231,7 +232,6 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file, if (pCifsFile == NULL) return pCifsFile; - pCifsFile->count = 1; pCifsFile->netfid = fileHandle; pCifsFile->pid = current->tgid; pCifsFile->uid = current_fsuid(); @@ -242,6 +242,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file, mutex_init(&pCifsFile->fh_mutex); mutex_init(&pCifsFile->lock_mutex); INIT_LIST_HEAD(&pCifsFile->llist); + atomic_set(&pCifsFile->count, 1); INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break); spin_lock(&cifs_file_list_lock); @@ -266,8 +267,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file, /* * Release a reference on the file private data. This may involve closing - * the filehandle out on the server. Must be called without holding - * cifs_file_list_lock. + * the filehandle out on the server. */ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) { @@ -276,7 +276,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) struct cifsLockInfo *li, *tmp; spin_lock(&cifs_file_list_lock); - if (--cifs_file->count > 0) { + if (!atomic_dec_and_test(&cifs_file->count)) { spin_unlock(&cifs_file_list_lock); return; } @@ -605,7 +605,8 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush) if (can_flush) { rc = filemap_write_and_wait(inode->i_mapping); - mapping_set_error(inode->i_mapping, rc); + if (rc != 0) + CIFS_I(inode)->write_behind_rc = rc; pCifsInode->clientCanCacheAll = false; pCifsInode->clientCanCacheRead = false; @@ -1352,7 +1353,6 @@ static int cifs_writepages(struct address_space *mapping, if (!experimEnabled && tcon->ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { cifsFileInfo_put(open_file); - kfree(iov); return generic_writepages(mapping, wbc); } cifsFileInfo_put(open_file); @@ -1478,7 +1478,12 @@ static int cifs_writepages(struct address_space *mapping, if (rc || bytes_written < bytes_to_write) { cERROR(1, "Write2 ret %d, wrote %d", rc, bytes_written); - mapping_set_error(mapping, rc); + /* BB what if continued retry is + requested via mount flags? */ + if (rc == -ENOSPC) + set_bit(AS_ENOSPC, &mapping->flags); + else + set_bit(AS_EIO, &mapping->flags); } else { cifs_stats_bytes_written(tcon, bytes_written); } @@ -1623,10 +1628,11 @@ int cifs_fsync(struct file *file, int datasync) rc = filemap_write_and_wait(inode->i_mapping); if (rc == 0) { - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - + rc = CIFS_I(inode)->write_behind_rc; + CIFS_I(inode)->write_behind_rc = 0; tcon = tlink_tcon(smbfile->tlink); - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) + if (!rc && tcon && smbfile && + !(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) rc = CIFSSMBFlush(xid, tcon, smbfile->netfid); } @@ -1671,8 +1677,21 @@ int cifs_flush(struct file *file, fl_owner_t id) struct inode *inode = file->f_path.dentry->d_inode; int rc = 0; - if (file->f_mode & FMODE_WRITE) - rc = filemap_write_and_wait(inode->i_mapping); + /* Rather than do the steps manually: + lock the inode for writing + loop through pages looking for write behind data (dirty pages) + coalesce into contiguous 16K (or smaller) chunks to write to server + send to server (prefer in parallel) + deal with writebehind errors + unlock inode for writing + filemapfdatawrite appears easier for the time being */ + + rc = filemap_fdatawrite(inode->i_mapping); + /* reset wb rc if we were able to write out dirty pages */ + if (!rc) { + rc = CIFS_I(inode)->write_behind_rc; + CIFS_I(inode)->write_behind_rc = 0; + } cFYI(1, "Flush inode %p file %p rc %d", inode, file, rc); @@ -2251,7 +2270,7 @@ void cifs_oplock_break(struct work_struct *work) oplock_break); struct inode *inode = cfile->dentry->d_inode; struct cifsInodeInfo *cinode = CIFS_I(inode); - int rc = 0; + int rc, waitrc = 0; if (inode && S_ISREG(inode->i_mode)) { if (cinode->clientCanCacheRead) @@ -2260,10 +2279,13 @@ void cifs_oplock_break(struct work_struct *work) break_lease(inode, O_WRONLY); rc = filemap_fdatawrite(inode->i_mapping); if (cinode->clientCanCacheRead == 0) { - rc = filemap_fdatawait(inode->i_mapping); - mapping_set_error(inode->i_mapping, rc); + waitrc = filemap_fdatawait(inode->i_mapping); invalidate_remote_inode(inode); } + if (!rc) + rc = waitrc; + if (rc) + cinode->write_behind_rc = rc; cFYI(1, "Oplock flush inode %p rc %d", inode, rc); } @@ -2282,7 +2304,7 @@ void cifs_oplock_break(struct work_struct *work) /* * We might have kicked in before is_valid_oplock_break() * finished grabbing reference for us. Make sure it's done by - * waiting for cifs_file_list_lock. + * waiting for GlobalSMSSeslock. */ spin_lock(&cifs_file_list_lock); spin_unlock(&cifs_file_list_lock); @@ -2290,7 +2312,6 @@ void cifs_oplock_break(struct work_struct *work) cifs_oplock_break_put(cfile); } -/* must be called while holding cifs_file_list_lock */ void cifs_oplock_break_get(struct cifsFileInfo *cfile) { cifs_sb_active(cfile->dentry->d_sb); diff --git a/trunk/fs/cifs/inode.c b/trunk/fs/cifs/inode.c index 39869c3c3efb..94979309698a 100644 --- a/trunk/fs/cifs/inode.c +++ b/trunk/fs/cifs/inode.c @@ -1682,7 +1682,8 @@ cifs_invalidate_mapping(struct inode *inode) /* write back any cached data */ if (inode->i_mapping && inode->i_mapping->nrpages != 0) { rc = filemap_write_and_wait(inode->i_mapping); - mapping_set_error(inode->i_mapping, rc); + if (rc) + cifs_i->write_behind_rc = rc; } invalidate_remote_inode(inode); cifs_fscache_reset_inode_cookie(inode); @@ -1942,8 +1943,10 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) * the flush returns error? */ rc = filemap_write_and_wait(inode->i_mapping); - mapping_set_error(inode->i_mapping, rc); - rc = 0; + if (rc != 0) { + cifsInode->write_behind_rc = rc; + rc = 0; + } if (attrs->ia_valid & ATTR_SIZE) { rc = cifs_set_file_size(inode, attrs, xid, full_path); @@ -2084,8 +2087,10 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) * the flush returns error? */ rc = filemap_write_and_wait(inode->i_mapping); - mapping_set_error(inode->i_mapping, rc); - rc = 0; + if (rc != 0) { + cifsInode->write_behind_rc = rc; + rc = 0; + } if (attrs->ia_valid & ATTR_SIZE) { rc = cifs_set_file_size(inode, attrs, xid, full_path); diff --git a/trunk/fs/cifs/misc.c b/trunk/fs/cifs/misc.c index c4e296fe3518..1c681f6a6803 100644 --- a/trunk/fs/cifs/misc.c +++ b/trunk/fs/cifs/misc.c @@ -577,7 +577,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) * cifs_oplock_break_put() can't be called * from here. Get reference after queueing * succeeded. cifs_oplock_break() will - * synchronize using cifs_file_list_lock. + * synchronize using GlobalSMSSeslock. */ if (queue_work(system_nrt_wq, &netfile->oplock_break)) diff --git a/trunk/fs/cifs/sess.c b/trunk/fs/cifs/sess.c index 7b01d3f6eed6..2a11efd96592 100644 --- a/trunk/fs/cifs/sess.c +++ b/trunk/fs/cifs/sess.c @@ -32,6 +32,9 @@ #include #include "cifs_spnego.h" +extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, + unsigned char *p24); + /* * Checks if this is the first smb session to be reconnected after * the socket has been reestablished (so we know whether to use vc 0). @@ -399,22 +402,23 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, return -EINVAL; } - memcpy(ses->ntlmssp->cryptkey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE); + memcpy(ses->cryptKey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE); /* BB we could decode pblob->NegotiateFlags; some may be useful */ /* In particular we can examine sign flags */ /* BB spec says that if AvId field of MsvAvTimestamp is populated then we must set the MIC field of the AUTHENTICATE_MESSAGE */ - ses->ntlmssp->server_flags = le32_to_cpu(pblob->NegotiateFlags); + tioffset = cpu_to_le16(pblob->TargetInfoArray.BufferOffset); tilen = cpu_to_le16(pblob->TargetInfoArray.Length); - if (tilen) { - ses->auth_key.response = kmalloc(tilen, GFP_KERNEL); - if (!ses->auth_key.response) { + ses->tilen = tilen; + if (ses->tilen) { + ses->tiblob = kmalloc(tilen, GFP_KERNEL); + if (!ses->tiblob) { cERROR(1, "Challenge target info allocation failure"); + ses->tilen = 0; return -ENOMEM; } - memcpy(ses->auth_key.response, bcc_ptr + tioffset, tilen); - ses->auth_key.len = tilen; + memcpy(ses->tiblob, bcc_ptr + tioffset, ses->tilen); } return 0; @@ -439,12 +443,10 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_NTLM; if (ses->server->secMode & - (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { + (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) flags |= NTLMSSP_NEGOTIATE_SIGN; - if (!ses->server->session_estab) - flags |= NTLMSSP_NEGOTIATE_KEY_XCH | - NTLMSSP_NEGOTIATE_EXTENDED_SEC; - } + if (ses->server->secMode & SECMODE_SIGN_REQUIRED) + flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; sec_blob->NegotiateFlags |= cpu_to_le32(flags); @@ -467,9 +469,11 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, const struct nls_table *nls_cp) { int rc; + unsigned int size; AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer; __u32 flags; unsigned char *tmp; + struct ntlmv2_resp ntlmv2_response = {}; memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); sec_blob->MessageType = NtLmAuthenticate; @@ -493,19 +497,25 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, sec_blob->LmChallengeResponse.MaximumLength = 0; sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer); - rc = setup_ntlmv2_rsp(ses, nls_cp); + rc = setup_ntlmv2_rsp(ses, (char *)&ntlmv2_response, nls_cp); if (rc) { cERROR(1, "Error %d during NTLMSSP authentication", rc); goto setup_ntlmv2_ret; } - memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE, - ses->auth_key.len - CIFS_SESS_KEY_SIZE); - tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE; + size = sizeof(struct ntlmv2_resp); + memcpy(tmp, (char *)&ntlmv2_response, size); + tmp += size; + if (ses->tilen > 0) { + memcpy(tmp, ses->tiblob, ses->tilen); + tmp += ses->tilen; + } - sec_blob->NtChallengeResponse.Length = - cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE); + sec_blob->NtChallengeResponse.Length = cpu_to_le16(size + ses->tilen); sec_blob->NtChallengeResponse.MaximumLength = - cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE); + cpu_to_le16(size + ses->tilen); + kfree(ses->tiblob); + ses->tiblob = NULL; + ses->tilen = 0; if (ses->domainName == NULL) { sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); @@ -544,19 +554,9 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, sec_blob->WorkstationName.MaximumLength = 0; tmp += 2; - if ((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) && - !calc_seckey(ses)) { - memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE); - sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); - sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE); - sec_blob->SessionKey.MaximumLength = - cpu_to_le16(CIFS_CPHTXT_SIZE); - tmp += CIFS_CPHTXT_SIZE; - } else { - sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); - sec_blob->SessionKey.Length = 0; - sec_blob->SessionKey.MaximumLength = 0; - } + sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); + sec_blob->SessionKey.Length = 0; + sec_blob->SessionKey.MaximumLength = 0; setup_ntlmv2_ret: *buflen = tmp - pbuffer; @@ -600,16 +600,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, return -EINVAL; type = ses->server->secType; - cFYI(1, "sess setup type %d", type); - if (type == RawNTLMSSP) { - /* if memory allocation is successful, caller of this function - * frees it. - */ - ses->ntlmssp = kmalloc(sizeof(struct ntlmssp_auth), GFP_KERNEL); - if (!ses->ntlmssp) - return -ENOMEM; - } + cFYI(1, "sess setup type %d", type); ssetup_ntlmssp_authenticate: if (phase == NtLmChallenge) phase = NtLmAuthenticate; /* if ntlmssp, now final phase */ @@ -674,14 +666,10 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, /* no capabilities flags in old lanman negotiation */ pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE); + /* BB calculate hash with password */ + /* and copy into bcc */ - /* Calculate hash with password and copy into bcc_ptr. - * Encryption Key (stored as in cryptkey) gets used if the - * security mode bit in Negottiate Protocol response states - * to use challenge/response method (i.e. Password bit is 1). - */ - - calc_lanman_hash(ses->password, ses->server->cryptkey, + calc_lanman_hash(ses->password, ses->cryptKey, ses->server->secMode & SECMODE_PW_ENCRYPT ? true : false, lnm_session_key); @@ -699,27 +687,24 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); #endif } else if (type == NTLM) { + char ntlm_session_key[CIFS_SESS_KEY_SIZE]; + pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); pSMB->req_no_secext.CaseInsensitivePasswordLength = - cpu_to_le16(CIFS_AUTH_RESP_SIZE); + cpu_to_le16(CIFS_SESS_KEY_SIZE); pSMB->req_no_secext.CaseSensitivePasswordLength = - cpu_to_le16(CIFS_AUTH_RESP_SIZE); - - /* calculate ntlm response and session key */ - rc = setup_ntlm_response(ses); - if (rc) { - cERROR(1, "Error %d during NTLM authentication", rc); - goto ssetup_exit; - } + cpu_to_le16(CIFS_SESS_KEY_SIZE); - /* copy ntlm response */ - memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE, - CIFS_AUTH_RESP_SIZE); - bcc_ptr += CIFS_AUTH_RESP_SIZE; - memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE, - CIFS_AUTH_RESP_SIZE); - bcc_ptr += CIFS_AUTH_RESP_SIZE; + /* calculate session key */ + SMBNTencrypt(ses->password, ses->cryptKey, ntlm_session_key); + cifs_calculate_session_key(&ses->auth_key, + ntlm_session_key, ses->password); + /* copy session key */ + memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE); + bcc_ptr += CIFS_SESS_KEY_SIZE; + memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE); + bcc_ptr += CIFS_SESS_KEY_SIZE; if (ses->capabilities & CAP_UNICODE) { /* unicode strings must be word aligned */ if (iov[0].iov_len % 2) { @@ -730,26 +715,47 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, } else ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); } else if (type == NTLMv2) { + char *v2_sess_key = + kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL); + + /* BB FIXME change all users of v2_sess_key to + struct ntlmv2_resp */ + + if (v2_sess_key == NULL) { + rc = -ENOMEM; + goto ssetup_exit; + } + pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); /* LM2 password would be here if we supported it */ pSMB->req_no_secext.CaseInsensitivePasswordLength = 0; + /* cpu_to_le16(LM2_SESS_KEY_SIZE); */ - /* calculate nlmv2 response and session key */ - rc = setup_ntlmv2_rsp(ses, nls_cp); + /* calculate session key */ + rc = setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); if (rc) { cERROR(1, "Error %d during NTLMv2 authentication", rc); + kfree(v2_sess_key); goto ssetup_exit; } - memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE, - ses->auth_key.len - CIFS_SESS_KEY_SIZE); - bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE; - + memcpy(bcc_ptr, (char *)v2_sess_key, + sizeof(struct ntlmv2_resp)); + bcc_ptr += sizeof(struct ntlmv2_resp); + kfree(v2_sess_key); /* set case sensitive password length after tilen may get * assigned, tilen is 0 otherwise. */ pSMB->req_no_secext.CaseSensitivePasswordLength = - cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE); + cpu_to_le16(sizeof(struct ntlmv2_resp) + ses->tilen); + if (ses->tilen > 0) { + memcpy(bcc_ptr, ses->tiblob, ses->tilen); + bcc_ptr += ses->tilen; + /* we never did allocate ses->domainName to free */ + kfree(ses->tiblob); + ses->tiblob = NULL; + ses->tilen = 0; + } if (ses->capabilities & CAP_UNICODE) { if (iov[0].iov_len % 2) { @@ -762,7 +768,6 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, } else if (type == Kerberos) { #ifdef CONFIG_CIFS_UPCALL struct cifs_spnego_msg *msg; - spnego_key = cifs_get_spnego_key(ses); if (IS_ERR(spnego_key)) { rc = PTR_ERR(spnego_key); @@ -780,17 +785,16 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, rc = -EKEYREJECTED; goto ssetup_exit; } - - ses->auth_key.response = kmalloc(msg->sesskey_len, GFP_KERNEL); - if (!ses->auth_key.response) { - cERROR(1, "Kerberos can't allocate (%u bytes) memory", - msg->sesskey_len); - rc = -ENOMEM; + /* bail out if key is too long */ + if (msg->sesskey_len > + sizeof(ses->auth_key.data.krb5)) { + cERROR(1, "Kerberos signing key too long (%u bytes)", + msg->sesskey_len); + rc = -EOVERFLOW; goto ssetup_exit; } - memcpy(ses->auth_key.response, msg->data, msg->sesskey_len); ses->auth_key.len = msg->sesskey_len; - + memcpy(ses->auth_key.data.krb5, msg->data, msg->sesskey_len); pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; capabilities |= CAP_EXTENDED_SECURITY; pSMB->req.Capabilities = cpu_to_le32(capabilities); @@ -893,6 +897,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR); /* SMB request buf freed in SendReceive2 */ + cFYI(1, "ssetup rc from sendrecv2 is %d", rc); + pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base; smb_buf = (struct smb_hdr *)iov[0].iov_base; diff --git a/trunk/fs/cifs/transport.c b/trunk/fs/cifs/transport.c index e0588cdf4cc5..a66c91eb6eb4 100644 --- a/trunk/fs/cifs/transport.c +++ b/trunk/fs/cifs/transport.c @@ -543,7 +543,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))) { rc = cifs_verify_signature(midQ->resp_buf, - ses->server, + &ses->server->session_key, midQ->sequence_number+1); if (rc) { cERROR(1, "Unexpected SMB signature"); @@ -731,7 +731,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))) { rc = cifs_verify_signature(out_buf, - ses->server, + &ses->server->session_key, midQ->sequence_number+1); if (rc) { cERROR(1, "Unexpected SMB signature"); @@ -981,7 +981,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))) { rc = cifs_verify_signature(out_buf, - ses->server, + &ses->server->session_key, midQ->sequence_number+1); if (rc) { cERROR(1, "Unexpected SMB signature"); diff --git a/trunk/fs/coda/inode.c b/trunk/fs/coda/inode.c index 5ea57c8c7f97..7993b96ca348 100644 --- a/trunk/fs/coda/inode.c +++ b/trunk/fs/coda/inode.c @@ -306,16 +306,16 @@ static int coda_statfs(struct dentry *dentry, struct kstatfs *buf) /* init_coda: used by filesystems.c to register coda */ -static struct dentry *coda_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int coda_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_nodev(fs_type, flags, data, coda_fill_super); + return get_sb_nodev(fs_type, flags, data, coda_fill_super, mnt); } struct file_system_type coda_fs_type = { .owner = THIS_MODULE, .name = "coda", - .mount = coda_mount, + .get_sb = coda_get_sb, .kill_sb = kill_anon_super, .fs_flags = FS_BINARY_MOUNTDATA, }; diff --git a/trunk/fs/compat.c b/trunk/fs/compat.c index ff66c0d7583d..52cfeb61da77 100644 --- a/trunk/fs/compat.c +++ b/trunk/fs/compat.c @@ -606,14 +606,14 @@ ssize_t compat_rw_copy_check_uvector(int type, /* * Single unix specification: * We should -EINVAL if an element length is not >= 0 and fitting an - * ssize_t. + * ssize_t. The total length is fitting an ssize_t * - * In Linux, the total length is limited to MAX_RW_COUNT, there is - * no overflow possibility. + * Be careful here because iov_len is a size_t not an ssize_t */ tot_len = 0; ret = -EINVAL; for (seg = 0; seg < nr_segs; seg++) { + compat_ssize_t tmp = tot_len; compat_uptr_t buf; compat_ssize_t len; @@ -624,13 +624,13 @@ ssize_t compat_rw_copy_check_uvector(int type, } if (len < 0) /* size_t not fitting in compat_ssize_t .. */ goto out; + tot_len += len; + if (tot_len < tmp) /* maths overflow on the compat_ssize_t */ + goto out; if (!access_ok(vrfy_dir(type), compat_ptr(buf), len)) { ret = -EFAULT; goto out; } - if (len > MAX_RW_COUNT - tot_len) - len = MAX_RW_COUNT - tot_len; - tot_len += len; iov->iov_base = compat_ptr(buf); iov->iov_len = (compat_size_t) len; uvector++; diff --git a/trunk/fs/configfs/mount.c b/trunk/fs/configfs/mount.c index 7d3607febe1c..8c8d64230c2d 100644 --- a/trunk/fs/configfs/mount.c +++ b/trunk/fs/configfs/mount.c @@ -104,16 +104,16 @@ static int configfs_fill_super(struct super_block *sb, void *data, int silent) return 0; } -static struct dentry *configfs_do_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int configfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_single(fs_type, flags, data, configfs_fill_super); + return get_sb_single(fs_type, flags, data, configfs_fill_super, mnt); } static struct file_system_type configfs_fs_type = { .owner = THIS_MODULE, .name = "configfs", - .mount = configfs_do_mount, + .get_sb = configfs_get_sb, .kill_sb = kill_litter_super, }; diff --git a/trunk/fs/cramfs/inode.c b/trunk/fs/cramfs/inode.c index 32fd5fe9ca0e..1e7a33028d33 100644 --- a/trunk/fs/cramfs/inode.c +++ b/trunk/fs/cramfs/inode.c @@ -533,16 +533,17 @@ static const struct super_operations cramfs_ops = { .statfs = cramfs_statfs, }; -static struct dentry *cramfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int cramfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, cramfs_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, cramfs_fill_super, + mnt); } static struct file_system_type cramfs_fs_type = { .owner = THIS_MODULE, .name = "cramfs", - .mount = cramfs_mount, + .get_sb = cramfs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/debugfs/inode.c b/trunk/fs/debugfs/inode.c index 37a8ca7c1222..a4ed8380e98a 100644 --- a/trunk/fs/debugfs/inode.c +++ b/trunk/fs/debugfs/inode.c @@ -135,17 +135,17 @@ static int debug_fill_super(struct super_block *sb, void *data, int silent) return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files); } -static struct dentry *debug_mount(struct file_system_type *fs_type, +static int debug_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, - void *data) + void *data, struct vfsmount *mnt) { - return mount_single(fs_type, flags, data, debug_fill_super); + return get_sb_single(fs_type, flags, data, debug_fill_super, mnt); } static struct file_system_type debug_fs_type = { .owner = THIS_MODULE, .name = "debugfs", - .mount = debug_mount, + .get_sb = debug_get_sb, .kill_sb = kill_litter_super, }; diff --git a/trunk/fs/devpts/inode.c b/trunk/fs/devpts/inode.c index 1bb547c9cad6..8b3ffd5b5235 100644 --- a/trunk/fs/devpts/inode.c +++ b/trunk/fs/devpts/inode.c @@ -331,7 +331,7 @@ static int compare_init_pts_sb(struct super_block *s, void *p) } /* - * devpts_mount() + * devpts_get_sb() * * If the '-o newinstance' mount option was specified, mount a new * (private) instance of devpts. PTYs created in this instance are @@ -345,20 +345,20 @@ static int compare_init_pts_sb(struct super_block *s, void *p) * semantics in devpts while preserving backward compatibility of the * current 'single-namespace' semantics. i.e all mounts of devpts * without the 'newinstance' mount option should bind to the initial - * kernel mount, like mount_single(). + * kernel mount, like get_sb_single(). * * Mounts with 'newinstance' option create a new, private namespace. * * NOTE: * - * For single-mount semantics, devpts cannot use mount_single(), - * because mount_single()/sget() find and use the super-block from + * For single-mount semantics, devpts cannot use get_sb_single(), + * because get_sb_single()/sget() find and use the super-block from * the most recent mount of devpts. But that recent mount may be a - * 'newinstance' mount and mount_single() would pick the newinstance + * 'newinstance' mount and get_sb_single() would pick the newinstance * super-block instead of the initial super-block. */ -static struct dentry *devpts_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int devpts_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { int error; struct pts_mount_opts opts; @@ -366,7 +366,7 @@ static struct dentry *devpts_mount(struct file_system_type *fs_type, error = parse_mount_options(data, PARSE_MOUNT, &opts); if (error) - return ERR_PTR(error); + return error; if (opts.newinstance) s = sget(fs_type, NULL, set_anon_super, NULL); @@ -374,7 +374,7 @@ static struct dentry *devpts_mount(struct file_system_type *fs_type, s = sget(fs_type, compare_init_pts_sb, set_anon_super, NULL); if (IS_ERR(s)) - return ERR_CAST(s); + return PTR_ERR(s); if (!s->s_root) { s->s_flags = flags; @@ -390,11 +390,13 @@ static struct dentry *devpts_mount(struct file_system_type *fs_type, if (error) goto out_undo_sget; - return dget(s->s_root); + simple_set_mnt(mnt, s); + + return 0; out_undo_sget: deactivate_locked_super(s); - return ERR_PTR(error); + return error; } #else @@ -402,10 +404,10 @@ static struct dentry *devpts_mount(struct file_system_type *fs_type, * This supports only the legacy single-instance semantics (no * multiple-instance semantics) */ -static struct dentry *devpts_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *data) +static int devpts_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_single(fs_type, flags, data, devpts_fill_super); + return get_sb_single(fs_type, flags, data, devpts_fill_super, mnt); } #endif @@ -419,7 +421,7 @@ static void devpts_kill_sb(struct super_block *sb) static struct file_system_type devpts_fs_type = { .name = "devpts", - .mount = devpts_mount, + .get_sb = devpts_get_sb, .kill_sb = devpts_kill_sb, }; diff --git a/trunk/fs/ecryptfs/ecryptfs_kernel.h b/trunk/fs/ecryptfs/ecryptfs_kernel.h index 413a3c48f0bb..40186b959429 100644 --- a/trunk/fs/ecryptfs/ecryptfs_kernel.h +++ b/trunk/fs/ecryptfs/ecryptfs_kernel.h @@ -377,7 +377,6 @@ struct ecryptfs_mount_crypt_stat { #define ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES 0x00000010 #define ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK 0x00000020 #define ECRYPTFS_GLOBAL_ENCFN_USE_FEK 0x00000040 -#define ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY 0x00000080 u32 flags; struct list_head global_auth_tok_list; struct mutex global_auth_tok_list_mutex; diff --git a/trunk/fs/ecryptfs/inode.c b/trunk/fs/ecryptfs/inode.c index 9d1a22d62765..3fbc94203380 100644 --- a/trunk/fs/ecryptfs/inode.c +++ b/trunk/fs/ecryptfs/inode.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include "ecryptfs_kernel.h" @@ -71,19 +70,15 @@ ecryptfs_create_underlying_file(struct inode *lower_dir_inode, struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); struct dentry *dentry_save; struct vfsmount *vfsmount_save; - unsigned int flags_save; int rc; dentry_save = nd->path.dentry; vfsmount_save = nd->path.mnt; - flags_save = nd->flags; nd->path.dentry = lower_dentry; nd->path.mnt = lower_mnt; - nd->flags &= ~LOOKUP_OPEN; rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd); nd->path.dentry = dentry_save; nd->path.mnt = vfsmount_save; - nd->flags = flags_save; return rc; } @@ -1113,8 +1108,10 @@ ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, rc = -EOPNOTSUPP; goto out; } - - rc = vfs_setxattr(lower_dentry, name, value, size, flags); + mutex_lock(&lower_dentry->d_inode->i_mutex); + rc = lower_dentry->d_inode->i_op->setxattr(lower_dentry, name, value, + size, flags); + mutex_unlock(&lower_dentry->d_inode->i_mutex); out: return rc; } diff --git a/trunk/fs/ecryptfs/keystore.c b/trunk/fs/ecryptfs/keystore.c index b1f6858a5223..73811cfa2ea4 100644 --- a/trunk/fs/ecryptfs/keystore.c +++ b/trunk/fs/ecryptfs/keystore.c @@ -446,7 +446,6 @@ ecryptfs_find_global_auth_tok_for_sig( */ static int ecryptfs_find_auth_tok_for_sig( - struct key **auth_tok_key, struct ecryptfs_auth_tok **auth_tok, struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig) @@ -454,21 +453,12 @@ ecryptfs_find_auth_tok_for_sig( struct ecryptfs_global_auth_tok *global_auth_tok; int rc = 0; - (*auth_tok_key) = NULL; (*auth_tok) = NULL; if (ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok, mount_crypt_stat, sig)) { + struct key *auth_tok_key; - /* if the flag ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY is set in the - * mount_crypt_stat structure, we prevent to use auth toks that - * are not inserted through the ecryptfs_add_global_auth_tok - * function. - */ - if (mount_crypt_stat->flags - & ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY) - return -EINVAL; - - rc = ecryptfs_keyring_auth_tok_for_sig(auth_tok_key, auth_tok, + rc = ecryptfs_keyring_auth_tok_for_sig(&auth_tok_key, auth_tok, sig); } else (*auth_tok) = global_auth_tok->global_auth_tok; @@ -519,7 +509,6 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, char *filename, size_t filename_size) { struct ecryptfs_write_tag_70_packet_silly_stack *s; - struct key *auth_tok_key = NULL; int rc = 0; s = kmalloc(sizeof(*s), GFP_KERNEL); @@ -617,7 +606,6 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, } dest[s->i++] = s->cipher_code; rc = ecryptfs_find_auth_tok_for_sig( - &auth_tok_key, &s->auth_tok, mount_crypt_stat, mount_crypt_stat->global_default_fnek_sig); if (rc) { @@ -765,8 +753,6 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, out_unlock: mutex_unlock(s->tfm_mutex); out: - if (auth_tok_key) - key_put(auth_tok_key); kfree(s); return rc; } @@ -812,7 +798,6 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, char *data, size_t max_packet_size) { struct ecryptfs_parse_tag_70_packet_silly_stack *s; - struct key *auth_tok_key = NULL; int rc = 0; (*packet_size) = 0; @@ -925,8 +910,7 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, * >= ECRYPTFS_MAX_IV_BYTES. */ memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES); s->desc.info = s->iv; - rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key, - &s->auth_tok, mount_crypt_stat, + rc = ecryptfs_find_auth_tok_for_sig(&s->auth_tok, mount_crypt_stat, s->fnek_sig_hex); if (rc) { printk(KERN_ERR "%s: Error attempting to find auth tok for " @@ -1002,8 +986,6 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, (*filename_size) = 0; (*filename) = NULL; } - if (auth_tok_key) - key_put(auth_tok_key); kfree(s); return rc; } @@ -1575,19 +1557,14 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, ECRYPTFS_VERSION_MAJOR, ECRYPTFS_VERSION_MINOR); rc = -EINVAL; - goto out_release_key; + goto out; } if ((*auth_tok)->token_type != ECRYPTFS_PASSWORD && (*auth_tok)->token_type != ECRYPTFS_PRIVATE_KEY) { printk(KERN_ERR "Invalid auth_tok structure " "returned from key query\n"); rc = -EINVAL; - goto out_release_key; - } -out_release_key: - if (rc) { - key_put(*auth_tok_key); - (*auth_tok_key) = NULL; + goto out; } out: return rc; @@ -1711,7 +1688,6 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, struct ecryptfs_auth_tok_list_item *auth_tok_list_item; size_t tag_11_contents_size; size_t tag_11_packet_size; - struct key *auth_tok_key = NULL; int rc = 0; INIT_LIST_HEAD(&auth_tok_list); @@ -1808,10 +1784,6 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, * just one will be sufficient to decrypt to get the FEK. */ find_next_matching_auth_tok: found_auth_tok = 0; - if (auth_tok_key) { - key_put(auth_tok_key); - auth_tok_key = NULL; - } list_for_each_entry(auth_tok_list_item, &auth_tok_list, list) { candidate_auth_tok = &auth_tok_list_item->auth_tok; if (unlikely(ecryptfs_verbosity > 0)) { @@ -1828,11 +1800,10 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, rc = -EINVAL; goto out_wipe_list; } - rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key, - &matching_auth_tok, + ecryptfs_find_auth_tok_for_sig(&matching_auth_tok, crypt_stat->mount_crypt_stat, candidate_auth_tok_sig); - if (!rc) { + if (matching_auth_tok) { found_auth_tok = 1; goto found_matching_auth_tok; } @@ -1895,8 +1866,6 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, out_wipe_list: wipe_auth_tok_list(&auth_tok_list); out: - if (auth_tok_key) - key_put(auth_tok_key); return rc; } diff --git a/trunk/fs/ecryptfs/main.c b/trunk/fs/ecryptfs/main.c index a9dbd62518e6..cbd4e18adb20 100644 --- a/trunk/fs/ecryptfs/main.c +++ b/trunk/fs/ecryptfs/main.c @@ -208,8 +208,7 @@ enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, ecryptfs_opt_passthrough, ecryptfs_opt_xattr_metadata, ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig, ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes, - ecryptfs_opt_unlink_sigs, ecryptfs_opt_mount_auth_tok_only, - ecryptfs_opt_err }; + ecryptfs_opt_unlink_sigs, ecryptfs_opt_err }; static const match_table_t tokens = { {ecryptfs_opt_sig, "sig=%s"}, @@ -224,7 +223,6 @@ static const match_table_t tokens = { {ecryptfs_opt_fn_cipher, "ecryptfs_fn_cipher=%s"}, {ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"}, {ecryptfs_opt_unlink_sigs, "ecryptfs_unlink_sigs"}, - {ecryptfs_opt_mount_auth_tok_only, "ecryptfs_mount_auth_tok_only"}, {ecryptfs_opt_err, NULL} }; @@ -408,10 +406,6 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) case ecryptfs_opt_unlink_sigs: mount_crypt_stat->flags |= ECRYPTFS_UNLINK_SIGS; break; - case ecryptfs_opt_mount_auth_tok_only: - mount_crypt_stat->flags |= - ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY; - break; case ecryptfs_opt_err: default: printk(KERN_WARNING @@ -546,8 +540,9 @@ static int ecryptfs_read_super(struct super_block *sb, const char *dev_name) * ecryptfs_interpose to perform most of the linking * ecryptfs_interpose(): links the lower filesystem into ecryptfs (inode.c) */ -static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *raw_data) +static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *raw_data, + struct vfsmount *mnt) { struct super_block *s; struct ecryptfs_sb_info *sbi; @@ -612,7 +607,8 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags err = "Reading sb failed"; goto out; } - return dget(s->s_root); + simple_set_mnt(mnt, s); + return 0; out: if (sbi) { @@ -620,7 +616,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags kmem_cache_free(ecryptfs_sb_info_cache, sbi); } printk(KERN_ERR "%s; rc = [%d]\n", err, rc); - return ERR_PTR(rc); + return rc; } /** @@ -643,7 +639,7 @@ static void ecryptfs_kill_block_super(struct super_block *sb) static struct file_system_type ecryptfs_fs_type = { .owner = THIS_MODULE, .name = "ecryptfs", - .mount = ecryptfs_mount, + .get_sb = ecryptfs_get_sb, .kill_sb = ecryptfs_kill_block_super, .fs_flags = 0 }; diff --git a/trunk/fs/ecryptfs/super.c b/trunk/fs/ecryptfs/super.c index 253732382d37..f7fc286a3aa9 100644 --- a/trunk/fs/ecryptfs/super.c +++ b/trunk/fs/ecryptfs/super.c @@ -180,8 +180,6 @@ static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt) seq_printf(m, ",ecryptfs_encrypted_view"); if (mount_crypt_stat->flags & ECRYPTFS_UNLINK_SIGS) seq_printf(m, ",ecryptfs_unlink_sigs"); - if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY) - seq_printf(m, ",ecryptfs_mount_auth_tok_only"); return 0; } diff --git a/trunk/fs/efs/super.c b/trunk/fs/efs/super.c index 5073a07652cc..f04942810818 100644 --- a/trunk/fs/efs/super.c +++ b/trunk/fs/efs/super.c @@ -20,16 +20,16 @@ static int efs_statfs(struct dentry *dentry, struct kstatfs *buf); static int efs_fill_super(struct super_block *s, void *d, int silent); -static struct dentry *efs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int efs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, efs_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, efs_fill_super, mnt); } static struct file_system_type efs_fs_type = { .owner = THIS_MODULE, .name = "efs", - .mount = efs_mount, + .get_sb = efs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/exofs/super.c b/trunk/fs/exofs/super.c index 79c3ae6e0456..047e92fa3af8 100644 --- a/trunk/fs/exofs/super.c +++ b/trunk/fs/exofs/super.c @@ -659,19 +659,19 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) /* * Set up the superblock (calls exofs_fill_super eventually) */ -static struct dentry *exofs_mount(struct file_system_type *type, +static int exofs_get_sb(struct file_system_type *type, int flags, const char *dev_name, - void *data) + void *data, struct vfsmount *mnt) { struct exofs_mountopt opts; int ret; ret = parse_options(data, &opts); if (ret) - return ERR_PTR(ret); + return ret; opts.dev_name = dev_name; - return mount_nodev(type, flags, &opts, exofs_fill_super); + return get_sb_nodev(type, flags, &opts, exofs_fill_super, mnt); } /* @@ -809,7 +809,7 @@ static const struct export_operations exofs_export_ops = { static struct file_system_type exofs_type = { .owner = THIS_MODULE, .name = "exofs", - .mount = exofs_mount, + .get_sb = exofs_get_sb, .kill_sb = generic_shutdown_super, }; diff --git a/trunk/fs/ext2/super.c b/trunk/fs/ext2/super.c index d89e0b6a2d78..0901320671da 100644 --- a/trunk/fs/ext2/super.c +++ b/trunk/fs/ext2/super.c @@ -1356,10 +1356,10 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) return 0; } -static struct dentry *ext2_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int ext2_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, ext2_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, ext2_fill_super, mnt); } #ifdef CONFIG_QUOTA @@ -1473,7 +1473,7 @@ static ssize_t ext2_quota_write(struct super_block *sb, int type, static struct file_system_type ext2_fs_type = { .owner = THIS_MODULE, .name = "ext2", - .mount = ext2_mount, + .get_sb = ext2_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/ext3/super.c b/trunk/fs/ext3/super.c index 2fedaf8b5012..db87413d3479 100644 --- a/trunk/fs/ext3/super.c +++ b/trunk/fs/ext3/super.c @@ -3020,16 +3020,16 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type, #endif -static struct dentry *ext3_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int ext3_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, ext3_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, ext3_fill_super, mnt); } static struct file_system_type ext3_fs_type = { .owner = THIS_MODULE, .name = "ext3", - .mount = ext3_mount, + .get_sb = ext3_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index 40131b777af6..0348ce066592 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -73,8 +73,8 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf); static int ext4_unfreeze(struct super_block *sb); static void ext4_write_super(struct super_block *sb); static int ext4_freeze(struct super_block *sb); -static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *data); +static int ext4_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, struct vfsmount *mnt); static void ext4_destroy_lazyinit_thread(void); static void ext4_unregister_li_request(struct super_block *sb); @@ -82,7 +82,7 @@ static void ext4_unregister_li_request(struct super_block *sb); static struct file_system_type ext3_fs_type = { .owner = THIS_MODULE, .name = "ext3", - .mount = ext4_mount, + .get_sb = ext4_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; @@ -4667,17 +4667,17 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, #endif -static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *data) +static int ext4_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, ext4_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt); } #if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) static struct file_system_type ext2_fs_type = { .owner = THIS_MODULE, .name = "ext2", - .mount = ext4_mount, + .get_sb = ext4_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; @@ -4722,7 +4722,7 @@ static inline void unregister_as_ext3(void) { } static struct file_system_type ext4_fs_type = { .owner = THIS_MODULE, .name = "ext4", - .mount = ext4_mount, + .get_sb = ext4_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/fat/namei_msdos.c b/trunk/fs/fat/namei_msdos.c index 3345aabd1dd7..bbca5c186ae7 100644 --- a/trunk/fs/fat/namei_msdos.c +++ b/trunk/fs/fat/namei_msdos.c @@ -675,17 +675,18 @@ static int msdos_fill_super(struct super_block *sb, void *data, int silent) return 0; } -static struct dentry *msdos_mount(struct file_system_type *fs_type, +static int msdos_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, - void *data) + void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, msdos_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, msdos_fill_super, + mnt); } static struct file_system_type msdos_fs_type = { .owner = THIS_MODULE, .name = "msdos", - .mount = msdos_mount, + .get_sb = msdos_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/fat/namei_vfat.c b/trunk/fs/fat/namei_vfat.c index b936703b8924..6f0f6c9a0152 100644 --- a/trunk/fs/fat/namei_vfat.c +++ b/trunk/fs/fat/namei_vfat.c @@ -1071,17 +1071,18 @@ static int vfat_fill_super(struct super_block *sb, void *data, int silent) return 0; } -static struct dentry *vfat_mount(struct file_system_type *fs_type, +static int vfat_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, - void *data) + void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, vfat_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, vfat_fill_super, + mnt); } static struct file_system_type vfat_fs_type = { .owner = THIS_MODULE, .name = "vfat", - .mount = vfat_mount, + .get_sb = vfat_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/freevxfs/vxfs_super.c b/trunk/fs/freevxfs/vxfs_super.c index 9d1c99558389..71b0148b8784 100644 --- a/trunk/fs/freevxfs/vxfs_super.c +++ b/trunk/fs/freevxfs/vxfs_super.c @@ -246,16 +246,17 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent) /* * The usual module blurb. */ -static struct dentry *vxfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int vxfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, vxfs_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, vxfs_fill_super, + mnt); } static struct file_system_type vxfs_fs_type = { .owner = THIS_MODULE, .name = "vxfs", - .mount = vxfs_mount, + .get_sb = vxfs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/fuse/control.c b/trunk/fs/fuse/control.c index 85542a7daf40..4eba07661e5c 100644 --- a/trunk/fs/fuse/control.c +++ b/trunk/fs/fuse/control.c @@ -322,10 +322,12 @@ static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent) return 0; } -static struct dentry *fuse_ctl_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *raw_data) +static int fuse_ctl_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *raw_data, + struct vfsmount *mnt) { - return mount_single(fs_type, flags, raw_data, fuse_ctl_fill_super); + return get_sb_single(fs_type, flags, raw_data, + fuse_ctl_fill_super, mnt); } static void fuse_ctl_kill_sb(struct super_block *sb) @@ -344,7 +346,7 @@ static void fuse_ctl_kill_sb(struct super_block *sb) static struct file_system_type fuse_ctl_fs_type = { .owner = THIS_MODULE, .name = "fusectl", - .mount = fuse_ctl_mount, + .get_sb = fuse_ctl_get_sb, .kill_sb = fuse_ctl_kill_sb, }; diff --git a/trunk/fs/fuse/inode.c b/trunk/fs/fuse/inode.c index cfce3ad86a92..da9e6e11374c 100644 --- a/trunk/fs/fuse/inode.c +++ b/trunk/fs/fuse/inode.c @@ -1041,11 +1041,11 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) return err; } -static struct dentry *fuse_mount(struct file_system_type *fs_type, +static int fuse_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, - void *raw_data) + void *raw_data, struct vfsmount *mnt) { - return mount_nodev(fs_type, flags, raw_data, fuse_fill_super); + return get_sb_nodev(fs_type, flags, raw_data, fuse_fill_super, mnt); } static void fuse_kill_sb_anon(struct super_block *sb) @@ -1065,16 +1065,17 @@ static struct file_system_type fuse_fs_type = { .owner = THIS_MODULE, .name = "fuse", .fs_flags = FS_HAS_SUBTYPE, - .mount = fuse_mount, + .get_sb = fuse_get_sb, .kill_sb = fuse_kill_sb_anon, }; #ifdef CONFIG_BLOCK -static struct dentry *fuse_mount_blk(struct file_system_type *fs_type, +static int fuse_get_sb_blk(struct file_system_type *fs_type, int flags, const char *dev_name, - void *raw_data) + void *raw_data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, raw_data, fuse_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, raw_data, fuse_fill_super, + mnt); } static void fuse_kill_sb_blk(struct super_block *sb) @@ -1093,7 +1094,7 @@ static void fuse_kill_sb_blk(struct super_block *sb) static struct file_system_type fuseblk_fs_type = { .owner = THIS_MODULE, .name = "fuseblk", - .mount = fuse_mount_blk, + .get_sb = fuse_get_sb_blk, .kill_sb = fuse_kill_sb_blk, .fs_flags = FS_REQUIRES_DEV | FS_HAS_SUBTYPE, }; diff --git a/trunk/fs/gfs2/ops_fstype.c b/trunk/fs/gfs2/ops_fstype.c index 3eb1393f7b81..cade1acbcea9 100644 --- a/trunk/fs/gfs2/ops_fstype.c +++ b/trunk/fs/gfs2/ops_fstype.c @@ -1250,11 +1250,12 @@ static int test_gfs2_super(struct super_block *s, void *ptr) } /** - * gfs2_mount - Get the GFS2 superblock + * gfs2_get_sb - Get the GFS2 superblock * @fs_type: The GFS2 filesystem type * @flags: Mount flags * @dev_name: The name of the device * @data: The mount arguments + * @mnt: The vfsmnt for this mount * * Q. Why not use get_sb_bdev() ? * A. We need to select one of two root directories to mount, independent @@ -1263,8 +1264,8 @@ static int test_gfs2_super(struct super_block *s, void *ptr) * Returns: 0 or -ve on error */ -static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *data) +static int gfs2_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, struct vfsmount *mnt) { struct block_device *bdev; struct super_block *s; @@ -1278,7 +1279,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, bdev = open_bdev_exclusive(dev_name, mode, fs_type); if (IS_ERR(bdev)) - return ERR_CAST(bdev); + return PTR_ERR(bdev); /* * once the super is inserted into the list by sget, s_umount @@ -1297,9 +1298,6 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, if (IS_ERR(s)) goto error_bdev; - if (s->s_root) - close_bdev_exclusive(bdev, mode); - memset(&args, 0, sizeof(args)); args.ar_quota = GFS2_QUOTA_DEFAULT; args.ar_data = GFS2_DATA_DEFAULT; @@ -1311,13 +1309,17 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, error = gfs2_mount_args(&args, data); if (error) { printk(KERN_WARNING "GFS2: can't parse mount arguments\n"); - goto error_super; + if (s->s_root) + goto error_super; + deactivate_locked_super(s); + return error; } if (s->s_root) { error = -EBUSY; if ((flags ^ s->s_flags) & MS_RDONLY) goto error_super; + close_bdev_exclusive(bdev, mode); } else { char b[BDEVNAME_SIZE]; @@ -1326,24 +1328,27 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); sb_set_blocksize(s, block_size(bdev)); error = fill_super(s, &args, flags & MS_SILENT ? 1 : 0); - if (error) - goto error_super; + if (error) { + deactivate_locked_super(s); + return error; + } s->s_flags |= MS_ACTIVE; bdev->bd_super = s; } sdp = s->s_fs_info; + mnt->mnt_sb = s; if (args.ar_meta) - return dget(sdp->sd_master_dir); + mnt->mnt_root = dget(sdp->sd_master_dir); else - return dget(sdp->sd_root_dir); + mnt->mnt_root = dget(sdp->sd_root_dir); + return 0; error_super: deactivate_locked_super(s); - return ERR_PTR(error); error_bdev: close_bdev_exclusive(bdev, mode); - return ERR_PTR(error); + return error; } static int set_meta_super(struct super_block *s, void *ptr) @@ -1351,8 +1356,8 @@ static int set_meta_super(struct super_block *s, void *ptr) return -EINVAL; } -static struct dentry *gfs2_mount_meta(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, struct vfsmount *mnt) { struct super_block *s; struct gfs2_sbd *sdp; @@ -1363,21 +1368,23 @@ static struct dentry *gfs2_mount_meta(struct file_system_type *fs_type, if (error) { printk(KERN_WARNING "GFS2: path_lookup on %s returned error %d\n", dev_name, error); - return ERR_PTR(error); + return error; } s = sget(&gfs2_fs_type, test_gfs2_super, set_meta_super, path.dentry->d_inode->i_sb->s_bdev); path_put(&path); if (IS_ERR(s)) { printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n"); - return ERR_CAST(s); + return PTR_ERR(s); } if ((flags ^ s->s_flags) & MS_RDONLY) { deactivate_locked_super(s); - return ERR_PTR(-EBUSY); + return -EBUSY; } sdp = s->s_fs_info; - return dget(sdp->sd_master_dir); + mnt->mnt_sb = s; + mnt->mnt_root = dget(sdp->sd_master_dir); + return 0; } static void gfs2_kill_sb(struct super_block *sb) @@ -1403,7 +1410,7 @@ static void gfs2_kill_sb(struct super_block *sb) struct file_system_type gfs2_fs_type = { .name = "gfs2", .fs_flags = FS_REQUIRES_DEV, - .mount = gfs2_mount, + .get_sb = gfs2_get_sb, .kill_sb = gfs2_kill_sb, .owner = THIS_MODULE, }; @@ -1411,7 +1418,7 @@ struct file_system_type gfs2_fs_type = { struct file_system_type gfs2meta_fs_type = { .name = "gfs2meta", .fs_flags = FS_REQUIRES_DEV, - .mount = gfs2_mount_meta, + .get_sb = gfs2_get_sb_meta, .owner = THIS_MODULE, }; diff --git a/trunk/fs/hfs/super.c b/trunk/fs/hfs/super.c index 4824c27cebb8..6ee1586f2334 100644 --- a/trunk/fs/hfs/super.c +++ b/trunk/fs/hfs/super.c @@ -441,16 +441,17 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent) return res; } -static struct dentry *hfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int hfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, + struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, hfs_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, hfs_fill_super, mnt); } static struct file_system_type hfs_fs_type = { .owner = THIS_MODULE, .name = "hfs", - .mount = hfs_mount, + .get_sb = hfs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/hfsplus/super.c b/trunk/fs/hfsplus/super.c index 52cc746d3ba3..9a88d7536103 100644 --- a/trunk/fs/hfsplus/super.c +++ b/trunk/fs/hfsplus/super.c @@ -495,16 +495,18 @@ static void hfsplus_destroy_inode(struct inode *inode) #define HFSPLUS_INODE_SIZE sizeof(struct hfsplus_inode_info) -static struct dentry *hfsplus_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int hfsplus_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, + struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, hfsplus_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, hfsplus_fill_super, + mnt); } static struct file_system_type hfsplus_fs_type = { .owner = THIS_MODULE, .name = "hfsplus", - .mount = hfsplus_mount, + .get_sb = hfsplus_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/hostfs/hostfs_kern.c b/trunk/fs/hostfs/hostfs_kern.c index 2c0f148a49e6..cd7c93917cc7 100644 --- a/trunk/fs/hostfs/hostfs_kern.c +++ b/trunk/fs/hostfs/hostfs_kern.c @@ -962,11 +962,11 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) return err; } -static struct dentry *hostfs_read_sb(struct file_system_type *type, +static int hostfs_read_sb(struct file_system_type *type, int flags, const char *dev_name, - void *data) + void *data, struct vfsmount *mnt) { - return mount_nodev(type, flags, data, hostfs_fill_sb_common); + return get_sb_nodev(type, flags, data, hostfs_fill_sb_common, mnt); } static void hostfs_kill_sb(struct super_block *s) @@ -978,7 +978,7 @@ static void hostfs_kill_sb(struct super_block *s) static struct file_system_type hostfs_type = { .owner = THIS_MODULE, .name = "hostfs", - .mount = hostfs_read_sb, + .get_sb = hostfs_read_sb, .kill_sb = hostfs_kill_sb, .fs_flags = 0, }; diff --git a/trunk/fs/hpfs/super.c b/trunk/fs/hpfs/super.c index bb69389972eb..c969a1aa163a 100644 --- a/trunk/fs/hpfs/super.c +++ b/trunk/fs/hpfs/super.c @@ -686,16 +686,17 @@ bail2: brelse(bh0); return -EINVAL; } -static struct dentry *hpfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int hpfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, hpfs_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, hpfs_fill_super, + mnt); } static struct file_system_type hpfs_fs_type = { .owner = THIS_MODULE, .name = "hpfs", - .mount = hpfs_mount, + .get_sb = hpfs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/hppfs/hppfs.c b/trunk/fs/hppfs/hppfs.c index f702b5f713fc..4e2a45ea6140 100644 --- a/trunk/fs/hppfs/hppfs.c +++ b/trunk/fs/hppfs/hppfs.c @@ -748,17 +748,17 @@ static int hppfs_fill_super(struct super_block *sb, void *d, int silent) return(err); } -static struct dentry *hppfs_read_super(struct file_system_type *type, +static int hppfs_read_super(struct file_system_type *type, int flags, const char *dev_name, - void *data) + void *data, struct vfsmount *mnt) { - return mount_nodev(type, flags, data, hppfs_fill_super); + return get_sb_nodev(type, flags, data, hppfs_fill_super, mnt); } static struct file_system_type hppfs_type = { .owner = THIS_MODULE, .name = "hppfs", - .mount = hppfs_read_super, + .get_sb = hppfs_read_super, .kill_sb = kill_anon_super, .fs_flags = 0, }; diff --git a/trunk/fs/hugetlbfs/inode.c b/trunk/fs/hugetlbfs/inode.c index d6cfac1f0a40..b14be3f781c7 100644 --- a/trunk/fs/hugetlbfs/inode.c +++ b/trunk/fs/hugetlbfs/inode.c @@ -896,15 +896,15 @@ void hugetlb_put_quota(struct address_space *mapping, long delta) } } -static struct dentry *hugetlbfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int hugetlbfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_nodev(fs_type, flags, data, hugetlbfs_fill_super); + return get_sb_nodev(fs_type, flags, data, hugetlbfs_fill_super, mnt); } static struct file_system_type hugetlbfs_fs_type = { .name = "hugetlbfs", - .mount = hugetlbfs_mount, + .get_sb = hugetlbfs_get_sb, .kill_sb = kill_litter_super, }; diff --git a/trunk/fs/internal.h b/trunk/fs/internal.h index e43b9a4dbf4e..ebad3b90752d 100644 --- a/trunk/fs/internal.h +++ b/trunk/fs/internal.h @@ -106,5 +106,5 @@ extern void release_open_intent(struct nameidata *); * inode.c */ extern int get_nr_dirty_inodes(void); -extern void evict_inodes(struct super_block *); +extern int evict_inodes(struct super_block *); extern int invalidate_inodes(struct super_block *); diff --git a/trunk/fs/isofs/inode.c b/trunk/fs/isofs/inode.c index bfdeb82a53be..79cf7f616bbe 100644 --- a/trunk/fs/isofs/inode.c +++ b/trunk/fs/isofs/inode.c @@ -1507,16 +1507,17 @@ struct inode *isofs_iget(struct super_block *sb, return inode; } -static struct dentry *isofs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int isofs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, isofs_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, isofs_fill_super, + mnt); } static struct file_system_type iso9660_fs_type = { .owner = THIS_MODULE, .name = "iso9660", - .mount = isofs_mount, + .get_sb = isofs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/jffs2/super.c b/trunk/fs/jffs2/super.c index c86041b866a4..d1ae5dfc22b9 100644 --- a/trunk/fs/jffs2/super.c +++ b/trunk/fs/jffs2/super.c @@ -179,11 +179,12 @@ static int jffs2_fill_super(struct super_block *sb, void *data, int silent) return ret; } -static struct dentry *jffs2_mount(struct file_system_type *fs_type, +static int jffs2_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, - void *data) + void *data, struct vfsmount *mnt) { - return mount_mtd(fs_type, flags, dev_name, data, jffs2_fill_super); + return get_sb_mtd(fs_type, flags, dev_name, data, jffs2_fill_super, + mnt); } static void jffs2_put_super (struct super_block *sb) @@ -228,7 +229,7 @@ static void jffs2_kill_sb(struct super_block *sb) static struct file_system_type jffs2_fs_type = { .owner = THIS_MODULE, .name = "jffs2", - .mount = jffs2_mount, + .get_sb = jffs2_get_sb, .kill_sb = jffs2_kill_sb, }; diff --git a/trunk/fs/jfs/super.c b/trunk/fs/jfs/super.c index 0669fc1cc3bf..68eee2bf629e 100644 --- a/trunk/fs/jfs/super.c +++ b/trunk/fs/jfs/super.c @@ -583,10 +583,11 @@ static int jfs_unfreeze(struct super_block *sb) return 0; } -static struct dentry *jfs_do_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int jfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, jfs_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, jfs_fill_super, + mnt); } static int jfs_sync_fs(struct super_block *sb, int wait) @@ -769,7 +770,7 @@ static const struct export_operations jfs_export_operations = { static struct file_system_type jfs_fs_type = { .owner = THIS_MODULE, .name = "jfs", - .mount = jfs_do_mount, + .get_sb = jfs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/libfs.c b/trunk/fs/libfs.c index a3accdf528ad..304a5132ca27 100644 --- a/trunk/fs/libfs.c +++ b/trunk/fs/libfs.c @@ -201,8 +201,9 @@ static const struct super_operations simple_super_operations = { * Common helper for pseudo-filesystems (sockfs, pipefs, bdev - stuff that * will never be mountable) */ -struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name, - const struct super_operations *ops, unsigned long magic) +int get_sb_pseudo(struct file_system_type *fs_type, char *name, + const struct super_operations *ops, unsigned long magic, + struct vfsmount *mnt) { struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL); struct dentry *dentry; @@ -210,7 +211,7 @@ struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name, struct qstr d_name = {.name = name, .len = strlen(name)}; if (IS_ERR(s)) - return ERR_CAST(s); + return PTR_ERR(s); s->s_flags = MS_NOUSER; s->s_maxbytes = MAX_LFS_FILESIZE; @@ -240,11 +241,12 @@ struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name, d_instantiate(dentry, root); s->s_root = dentry; s->s_flags |= MS_ACTIVE; - return dget(s->s_root); + simple_set_mnt(mnt, s); + return 0; Enomem: deactivate_locked_super(s); - return ERR_PTR(-ENOMEM); + return -ENOMEM; } int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) @@ -949,7 +951,7 @@ EXPORT_SYMBOL(dcache_dir_lseek); EXPORT_SYMBOL(dcache_dir_open); EXPORT_SYMBOL(dcache_readdir); EXPORT_SYMBOL(generic_read_dir); -EXPORT_SYMBOL(mount_pseudo); +EXPORT_SYMBOL(get_sb_pseudo); EXPORT_SYMBOL(simple_write_begin); EXPORT_SYMBOL(simple_write_end); EXPORT_SYMBOL(simple_dir_inode_operations); diff --git a/trunk/fs/logfs/dev_bdev.c b/trunk/fs/logfs/dev_bdev.c index 92ca6fbe09bd..9bd2ce2a3040 100644 --- a/trunk/fs/logfs/dev_bdev.c +++ b/trunk/fs/logfs/dev_bdev.c @@ -298,9 +298,9 @@ static int bdev_write_sb(struct super_block *sb, struct page *page) return sync_request(page, bdev, WRITE); } -static void bdev_put_device(struct logfs_super *s) +static void bdev_put_device(struct super_block *sb) { - close_bdev_exclusive(s->s_bdev, FMODE_READ|FMODE_WRITE); + close_bdev_exclusive(logfs_super(sb)->s_bdev, FMODE_READ|FMODE_WRITE); } static int bdev_can_write_buf(struct super_block *sb, u64 ofs) @@ -320,8 +320,8 @@ static const struct logfs_device_ops bd_devops = { .put_device = bdev_put_device, }; -int logfs_get_sb_bdev(struct logfs_super *p, struct file_system_type *type, - const char *devname) +int logfs_get_sb_bdev(struct file_system_type *type, int flags, + const char *devname, struct vfsmount *mnt) { struct block_device *bdev; @@ -332,11 +332,8 @@ int logfs_get_sb_bdev(struct logfs_super *p, struct file_system_type *type, if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) { int mtdnr = MINOR(bdev->bd_dev); close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE); - return logfs_get_sb_mtd(p, mtdnr); + return logfs_get_sb_mtd(type, flags, mtdnr, mnt); } - p->s_bdev = bdev; - p->s_mtd = NULL; - p->s_devops = &bd_devops; - return 0; + return logfs_get_sb_device(type, flags, NULL, bdev, &bd_devops, mnt); } diff --git a/trunk/fs/logfs/dev_mtd.c b/trunk/fs/logfs/dev_mtd.c index 7466e9dcc8c5..a85d47d13e4b 100644 --- a/trunk/fs/logfs/dev_mtd.c +++ b/trunk/fs/logfs/dev_mtd.c @@ -230,9 +230,9 @@ static void mtd_writeseg(struct super_block *sb, u64 ofs, size_t len) __mtd_writeseg(sb, ofs, ofs >> PAGE_SHIFT, len >> PAGE_SHIFT); } -static void mtd_put_device(struct logfs_super *s) +static void mtd_put_device(struct super_block *sb) { - put_mtd_device(s->s_mtd); + put_mtd_device(logfs_super(sb)->s_mtd); } static int mtd_can_write_buf(struct super_block *sb, u64 ofs) @@ -265,14 +265,14 @@ static const struct logfs_device_ops mtd_devops = { .put_device = mtd_put_device, }; -int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr) +int logfs_get_sb_mtd(struct file_system_type *type, int flags, + int mtdnr, struct vfsmount *mnt) { - struct mtd_info *mtd = get_mtd_device(NULL, mtdnr); + struct mtd_info *mtd; + const struct logfs_device_ops *devops = &mtd_devops; + + mtd = get_mtd_device(NULL, mtdnr); if (IS_ERR(mtd)) return PTR_ERR(mtd); - - s->s_bdev = NULL; - s->s_mtd = mtd; - s->s_devops = &mtd_devops; - return 0; + return logfs_get_sb_device(type, flags, mtd, NULL, devops, mnt); } diff --git a/trunk/fs/logfs/logfs.h b/trunk/fs/logfs/logfs.h index cd51a36b37f0..b8786264d243 100644 --- a/trunk/fs/logfs/logfs.h +++ b/trunk/fs/logfs/logfs.h @@ -136,7 +136,6 @@ struct logfs_area_ops { int (*erase_segment)(struct logfs_area *area); }; -struct logfs_super; /* forward */ /** * struct logfs_device_ops - device access operations * @@ -157,7 +156,7 @@ struct logfs_device_ops { int ensure_write); int (*can_write_buf)(struct super_block *sb, u64 ofs); void (*sync)(struct super_block *sb); - void (*put_device)(struct logfs_super *s); + void (*put_device)(struct super_block *sb); }; /** @@ -472,13 +471,11 @@ void logfs_compr_exit(void); /* dev_bdev.c */ #ifdef CONFIG_BLOCK -int logfs_get_sb_bdev(struct logfs_super *s, - struct file_system_type *type, - const char *devname); +int logfs_get_sb_bdev(struct file_system_type *type, int flags, + const char *devname, struct vfsmount *mnt); #else -static inline int logfs_get_sb_bdev(struct logfs_super *s, - struct file_system_type *type, - const char *devname) +static inline int logfs_get_sb_bdev(struct file_system_type *type, int flags, + const char *devname, struct vfsmount *mnt) { return -ENODEV; } @@ -486,9 +483,11 @@ static inline int logfs_get_sb_bdev(struct logfs_super *s, /* dev_mtd.c */ #ifdef CONFIG_MTD -int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr) +int logfs_get_sb_mtd(struct file_system_type *type, int flags, + int mtdnr, struct vfsmount *mnt); #else -static inline int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr) +static inline int logfs_get_sb_mtd(struct file_system_type *type, int flags, + int mtdnr, struct vfsmount *mnt) { return -ENODEV; } @@ -620,6 +619,9 @@ void emergency_read_end(struct page *page); void logfs_crash_dump(struct super_block *sb); void *memchr_inv(const void *s, int c, size_t n); int logfs_statfs(struct dentry *dentry, struct kstatfs *stats); +int logfs_get_sb_device(struct file_system_type *type, int flags, + struct mtd_info *mtd, struct block_device *bdev, + const struct logfs_device_ops *devops, struct vfsmount *mnt); int logfs_check_ds(struct logfs_disk_super *ds); int logfs_write_sb(struct super_block *sb); diff --git a/trunk/fs/logfs/super.c b/trunk/fs/logfs/super.c index 33435e4b14d2..5336155c5d81 100644 --- a/trunk/fs/logfs/super.c +++ b/trunk/fs/logfs/super.c @@ -325,7 +325,7 @@ static int logfs_make_writeable(struct super_block *sb) return 0; } -static int logfs_get_sb_final(struct super_block *sb) +static int logfs_get_sb_final(struct super_block *sb, struct vfsmount *mnt) { struct logfs_super *super = logfs_super(sb); struct inode *rootdir; @@ -356,6 +356,7 @@ static int logfs_get_sb_final(struct super_block *sb) } log_super("LogFS: Finished mounting\n"); + simple_set_mnt(mnt, sb); return 0; fail: @@ -528,37 +529,43 @@ static void logfs_kill_sb(struct super_block *sb) logfs_cleanup_rw(sb); if (super->s_erase_page) __free_page(super->s_erase_page); - super->s_devops->put_device(super); + super->s_devops->put_device(sb); logfs_mempool_destroy(super->s_btree_pool); logfs_mempool_destroy(super->s_alias_pool); kfree(super); log_super("LogFS: Finished unmounting\n"); } -static struct dentry *logfs_get_sb_device(struct logfs_super *super, - struct file_system_type *type, int flags) +int logfs_get_sb_device(struct file_system_type *type, int flags, + struct mtd_info *mtd, struct block_device *bdev, + const struct logfs_device_ops *devops, struct vfsmount *mnt) { + struct logfs_super *super; struct super_block *sb; int err = -ENOMEM; static int mount_count; log_super("LogFS: Start mount %x\n", mount_count++); + super = kzalloc(sizeof(*super), GFP_KERNEL); + if (!super) + goto err0; + super->s_mtd = mtd; + super->s_bdev = bdev; err = -EINVAL; sb = sget(type, logfs_sb_test, logfs_sb_set, super); - if (IS_ERR(sb)) { - super->s_devops->put_device(super); - kfree(super); - return ERR_CAST(sb); - } + if (IS_ERR(sb)) + goto err0; if (sb->s_root) { /* Device is already in use */ - super->s_devops->put_device(super); - kfree(super); - return dget(sb->s_root); + err = 0; + simple_set_mnt(mnt, sb); + goto err0; } + super->s_devops = devops; + /* * sb->s_maxbytes is limited to 8TB. On 32bit systems, the page cache * only covers 16TB and the upper 8TB are used for indirect blocks. @@ -574,12 +581,10 @@ static struct dentry *logfs_get_sb_device(struct logfs_super *super, goto err1; sb->s_flags |= MS_ACTIVE; - err = logfs_get_sb_final(sb); - if (err) { + err = logfs_get_sb_final(sb, mnt); + if (err) deactivate_locked_super(sb); - return ERR_PTR(err); - } - return dget(sb->s_root); + return err; err1: /* no ->s_root, no ->put_super() */ @@ -587,45 +592,37 @@ static struct dentry *logfs_get_sb_device(struct logfs_super *super, iput(super->s_segfile_inode); iput(super->s_mapping_inode); deactivate_locked_super(sb); - return ERR_PTR(err); + return err; +err0: + kfree(super); + //devops->put_device(sb); + return err; } -static struct dentry *logfs_mount(struct file_system_type *type, int flags, - const char *devname, void *data) +static int logfs_get_sb(struct file_system_type *type, int flags, + const char *devname, void *data, struct vfsmount *mnt) { ulong mtdnr; - struct logfs_super *super; - int err; - - super = kzalloc(sizeof(*super), GFP_KERNEL); - if (!super) - return ERR_PTR(-ENOMEM); if (!devname) - err = logfs_get_sb_bdev(super, type, devname); - else if (strncmp(devname, "mtd", 3)) - err = logfs_get_sb_bdev(super, type, devname); - else { + return logfs_get_sb_bdev(type, flags, devname, mnt); + if (strncmp(devname, "mtd", 3)) + return logfs_get_sb_bdev(type, flags, devname, mnt); + + { char *garbage; mtdnr = simple_strtoul(devname+3, &garbage, 0); if (*garbage) - err = -EINVAL; - else - err = logfs_get_sb_mtd(super, mtdnr); - } - - if (err) { - kfree(super); - return ERR_PTR(err); + return -EINVAL; } - return logfs_get_sb_device(super, type, flags); + return logfs_get_sb_mtd(type, flags, mtdnr, mnt); } static struct file_system_type logfs_fs_type = { .owner = THIS_MODULE, .name = "logfs", - .mount = logfs_mount, + .get_sb = logfs_get_sb, .kill_sb = logfs_kill_sb, .fs_flags = FS_REQUIRES_DEV, diff --git a/trunk/fs/minix/inode.c b/trunk/fs/minix/inode.c index fb2020858a34..e39d6bf2e8fb 100644 --- a/trunk/fs/minix/inode.c +++ b/trunk/fs/minix/inode.c @@ -614,16 +614,17 @@ void minix_truncate(struct inode * inode) V2_minix_truncate(inode); } -static struct dentry *minix_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int minix_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, minix_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, minix_fill_super, + mnt); } static struct file_system_type minix_fs_type = { .owner = THIS_MODULE, .name = "minix", - .mount = minix_mount, + .get_sb = minix_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index 5362af9b7372..f7dbc06857ab 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -1574,7 +1574,6 @@ static struct file *finish_open(struct nameidata *nd, */ if (will_truncate) mnt_drop_write(nd->path.mnt); - path_put(&nd->path); return filp; exit: @@ -1676,7 +1675,6 @@ static struct file *do_last(struct nameidata *nd, struct path *path, } filp = nameidata_to_filp(nd); mnt_drop_write(nd->path.mnt); - path_put(&nd->path); if (!IS_ERR(filp)) { error = ima_file_check(filp, acc_mode); if (error) { diff --git a/trunk/fs/ncpfs/inode.c b/trunk/fs/ncpfs/inode.c index d290545aa0c4..985fabb26aca 100644 --- a/trunk/fs/ncpfs/inode.c +++ b/trunk/fs/ncpfs/inode.c @@ -1020,16 +1020,16 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr) return result; } -static struct dentry *ncp_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int ncp_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_nodev(fs_type, flags, data, ncp_fill_super); + return get_sb_nodev(fs_type, flags, data, ncp_fill_super, mnt); } static struct file_system_type ncp_fs_type = { .owner = THIS_MODULE, .name = "ncpfs", - .mount = ncp_mount, + .get_sb = ncp_get_sb, .kill_sb = kill_anon_super, .fs_flags = FS_BINARY_MOUNTDATA, }; diff --git a/trunk/fs/nfs/super.c b/trunk/fs/nfs/super.c index 0a42e8f4adcb..3600ec700d58 100644 --- a/trunk/fs/nfs/super.c +++ b/trunk/fs/nfs/super.c @@ -260,8 +260,8 @@ static int nfs_statfs(struct dentry *, struct kstatfs *); static int nfs_show_options(struct seq_file *, struct vfsmount *); static int nfs_show_stats(struct seq_file *, struct vfsmount *); static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *); -static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *raw_data); +static int nfs_xdev_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); static void nfs_put_super(struct super_block *); static void nfs_kill_super(struct super_block *); static int nfs_remount(struct super_block *sb, int *flags, char *raw_data); @@ -277,7 +277,7 @@ static struct file_system_type nfs_fs_type = { struct file_system_type nfs_xdev_fs_type = { .owner = THIS_MODULE, .name = "nfs", - .mount = nfs_xdev_mount, + .get_sb = nfs_xdev_get_sb, .kill_sb = nfs_kill_super, .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, }; @@ -302,14 +302,14 @@ static int nfs4_try_mount(int flags, const char *dev_name, struct nfs_parsed_mount_data *data, struct vfsmount *mnt); static int nfs4_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); -static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *raw_data); -static struct dentry *nfs4_xdev_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *raw_data); +static int nfs4_remote_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); +static int nfs4_xdev_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); -static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *raw_data); +static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); static void nfs4_kill_super(struct super_block *sb); static struct file_system_type nfs4_fs_type = { @@ -323,7 +323,7 @@ static struct file_system_type nfs4_fs_type = { static struct file_system_type nfs4_remote_fs_type = { .owner = THIS_MODULE, .name = "nfs4", - .mount = nfs4_remote_mount, + .get_sb = nfs4_remote_get_sb, .kill_sb = nfs4_kill_super, .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, }; @@ -331,7 +331,7 @@ static struct file_system_type nfs4_remote_fs_type = { struct file_system_type nfs4_xdev_fs_type = { .owner = THIS_MODULE, .name = "nfs4", - .mount = nfs4_xdev_mount, + .get_sb = nfs4_xdev_get_sb, .kill_sb = nfs4_kill_super, .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, }; @@ -339,7 +339,7 @@ struct file_system_type nfs4_xdev_fs_type = { static struct file_system_type nfs4_remote_referral_fs_type = { .owner = THIS_MODULE, .name = "nfs4", - .mount = nfs4_remote_referral_mount, + .get_sb = nfs4_remote_referral_get_sb, .kill_sb = nfs4_kill_super, .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, }; @@ -2397,9 +2397,9 @@ static void nfs_kill_super(struct super_block *s) /* * Clone an NFS2/3 server record on xdev traversal (FSID-change) */ -static struct dentry * -nfs_xdev_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *raw_data) +static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *raw_data, + struct vfsmount *mnt) { struct nfs_clone_mount *data = raw_data; struct super_block *s; @@ -2411,7 +2411,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags, }; int error; - dprintk("--> nfs_xdev_mount()\n"); + dprintk("--> nfs_xdev_get_sb()\n"); /* create a new volume representation */ server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr); @@ -2458,26 +2458,28 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags, } s->s_flags |= MS_ACTIVE; + mnt->mnt_sb = s; + mnt->mnt_root = mntroot; /* clone any lsm security options from the parent to the new sb */ security_sb_clone_mnt_opts(data->sb, s); - dprintk("<-- nfs_xdev_mount() = 0\n"); - return mntroot; + dprintk("<-- nfs_xdev_get_sb() = 0\n"); + return 0; out_err_nosb: nfs_free_server(server); out_err_noserver: - dprintk("<-- nfs_xdev_mount() = %d [error]\n", error); - return ERR_PTR(error); + dprintk("<-- nfs_xdev_get_sb() = %d [error]\n", error); + return error; error_splat_super: if (server && !s->s_root) bdi_unregister(&server->backing_dev_info); error_splat_bdi: deactivate_locked_super(s); - dprintk("<-- nfs_xdev_mount() = %d [splat]\n", error); - return ERR_PTR(error); + dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error); + return error; } #ifdef CONFIG_NFS_V4 @@ -2647,9 +2649,8 @@ static int nfs4_validate_mount_data(void *options, /* * Get the superblock for the NFS4 root partition */ -static struct dentry * -nfs4_remote_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *raw_data) +static int nfs4_remote_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) { struct nfs_parsed_mount_data *data = raw_data; struct super_block *s; @@ -2713,16 +2714,15 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags, goto error_splat_root; s->s_flags |= MS_ACTIVE; - - security_free_mnt_opts(&data->lsm_opts); - nfs_free_fhandle(mntfh); - return mntroot; + mnt->mnt_sb = s; + mnt->mnt_root = mntroot; + error = 0; out: security_free_mnt_opts(&data->lsm_opts); out_free_fh: nfs_free_fhandle(mntfh); - return ERR_PTR(error); + return error; out_free: nfs_free_server(server); @@ -2968,9 +2968,9 @@ static void nfs4_kill_super(struct super_block *sb) /* * Clone an NFS4 server record on xdev traversal (FSID-change) */ -static struct dentry * -nfs4_xdev_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *raw_data) +static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *raw_data, + struct vfsmount *mnt) { struct nfs_clone_mount *data = raw_data; struct super_block *s; @@ -2982,7 +2982,7 @@ nfs4_xdev_mount(struct file_system_type *fs_type, int flags, }; int error; - dprintk("--> nfs4_xdev_mount()\n"); + dprintk("--> nfs4_xdev_get_sb()\n"); /* create a new volume representation */ server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr); @@ -3029,30 +3029,32 @@ nfs4_xdev_mount(struct file_system_type *fs_type, int flags, } s->s_flags |= MS_ACTIVE; + mnt->mnt_sb = s; + mnt->mnt_root = mntroot; security_sb_clone_mnt_opts(data->sb, s); - dprintk("<-- nfs4_xdev_mount() = 0\n"); - return mntroot; + dprintk("<-- nfs4_xdev_get_sb() = 0\n"); + return 0; out_err_nosb: nfs_free_server(server); out_err_noserver: - dprintk("<-- nfs4_xdev_mount() = %d [error]\n", error); - return ERR_PTR(error); + dprintk("<-- nfs4_xdev_get_sb() = %d [error]\n", error); + return error; error_splat_super: if (server && !s->s_root) bdi_unregister(&server->backing_dev_info); error_splat_bdi: deactivate_locked_super(s); - dprintk("<-- nfs4_xdev_mount() = %d [splat]\n", error); - return ERR_PTR(error); + dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error); + return error; } -static struct dentry * -nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *raw_data) +static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *raw_data, + struct vfsmount *mnt) { struct nfs_clone_mount *data = raw_data; struct super_block *s; @@ -3116,12 +3118,14 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, } s->s_flags |= MS_ACTIVE; + mnt->mnt_sb = s; + mnt->mnt_root = mntroot; security_sb_clone_mnt_opts(data->sb, s); nfs_free_fhandle(mntfh); dprintk("<-- nfs4_referral_get_sb() = 0\n"); - return mntroot; + return 0; out_err_nosb: nfs_free_server(server); @@ -3129,7 +3133,7 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, nfs_free_fhandle(mntfh); out_err_nofh: dprintk("<-- nfs4_referral_get_sb() = %d [error]\n", error); - return ERR_PTR(error); + return error; error_splat_super: if (server && !s->s_root) @@ -3138,7 +3142,7 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, deactivate_locked_super(s); nfs_free_fhandle(mntfh); dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error); - return ERR_PTR(error); + return error; } /* diff --git a/trunk/fs/nfs/unlink.c b/trunk/fs/nfs/unlink.c index 7bdec8531400..9a16bad5d2ea 100644 --- a/trunk/fs/nfs/unlink.c +++ b/trunk/fs/nfs/unlink.c @@ -444,9 +444,9 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir, /* set up nfs_renamedata */ data->old_dir = old_dir; - ihold(old_dir); + atomic_inc(&old_dir->i_count); data->new_dir = new_dir; - ihold(new_dir); + atomic_inc(&new_dir->i_count); data->old_dentry = dget(old_dentry); data->new_dentry = dget(new_dentry); nfs_fattr_init(&data->old_fattr); diff --git a/trunk/fs/nfsd/nfsctl.c b/trunk/fs/nfsd/nfsctl.c index 4514ebbee4d6..d6dc3f61f8ba 100644 --- a/trunk/fs/nfsd/nfsctl.c +++ b/trunk/fs/nfsd/nfsctl.c @@ -1405,16 +1405,16 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent) return simple_fill_super(sb, 0x6e667364, nfsd_files); } -static struct dentry *nfsd_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int nfsd_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_single(fs_type, flags, data, nfsd_fill_super); + return get_sb_single(fs_type, flags, data, nfsd_fill_super, mnt); } static struct file_system_type nfsd_fs_type = { .owner = THIS_MODULE, .name = "nfsd", - .mount = nfsd_mount, + .get_sb = nfsd_get_sb, .kill_sb = kill_litter_super, }; diff --git a/trunk/fs/nilfs2/super.c b/trunk/fs/nilfs2/super.c index f804d41ec9d3..35ae03c0db86 100644 --- a/trunk/fs/nilfs2/super.c +++ b/trunk/fs/nilfs2/super.c @@ -1141,9 +1141,9 @@ static int nilfs_test_bdev_super(struct super_block *s, void *data) return (void *)s->s_bdev == data; } -static struct dentry * -nilfs_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *data) +static int +nilfs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, struct vfsmount *mnt) { struct nilfs_super_data sd; struct super_block *s; @@ -1156,7 +1156,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags, sd.bdev = open_bdev_exclusive(dev_name, mode, fs_type); if (IS_ERR(sd.bdev)) - return ERR_CAST(sd.bdev); + return PTR_ERR(sd.bdev); sd.cno = 0; sd.flags = flags; @@ -1235,7 +1235,9 @@ nilfs_mount(struct file_system_type *fs_type, int flags, if (!s_new) close_bdev_exclusive(sd.bdev, mode); - return root_dentry; + mnt->mnt_sb = s; + mnt->mnt_root = root_dentry; + return 0; failed_super: deactivate_locked_super(s); @@ -1243,13 +1245,13 @@ nilfs_mount(struct file_system_type *fs_type, int flags, failed: if (!s_new) close_bdev_exclusive(sd.bdev, mode); - return ERR_PTR(err); + return err; } struct file_system_type nilfs_fs_type = { .owner = THIS_MODULE, .name = "nilfs2", - .mount = nilfs_mount, + .get_sb = nilfs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/ntfs/super.c b/trunk/fs/ntfs/super.c index a30ecacc01f2..d3fbe5730bfc 100644 --- a/trunk/fs/ntfs/super.c +++ b/trunk/fs/ntfs/super.c @@ -3059,16 +3059,17 @@ struct kmem_cache *ntfs_index_ctx_cache; /* Driver wide mutex. */ DEFINE_MUTEX(ntfs_lock); -static struct dentry *ntfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int ntfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, ntfs_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, ntfs_fill_super, + mnt); } static struct file_system_type ntfs_fs_type = { .owner = THIS_MODULE, .name = "ntfs", - .mount = ntfs_mount, + .get_sb = ntfs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/ocfs2/dlmfs/dlmfs.c b/trunk/fs/ocfs2/dlmfs/dlmfs.c index b2df490a19ed..75e115f1bd73 100644 --- a/trunk/fs/ocfs2/dlmfs/dlmfs.c +++ b/trunk/fs/ocfs2/dlmfs/dlmfs.c @@ -643,16 +643,16 @@ static const struct inode_operations dlmfs_file_inode_operations = { .setattr = dlmfs_file_setattr, }; -static struct dentry *dlmfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int dlmfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_nodev(fs_type, flags, data, dlmfs_fill_super); + return get_sb_nodev(fs_type, flags, data, dlmfs_fill_super, mnt); } static struct file_system_type dlmfs_fs_type = { .owner = THIS_MODULE, .name = "ocfs2_dlmfs", - .mount = dlmfs_mount, + .get_sb = dlmfs_get_sb, .kill_sb = kill_litter_super, }; diff --git a/trunk/fs/ocfs2/super.c b/trunk/fs/ocfs2/super.c index f02c0ef31578..56f0cb395820 100644 --- a/trunk/fs/ocfs2/super.c +++ b/trunk/fs/ocfs2/super.c @@ -1236,12 +1236,14 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) return status; } -static struct dentry *ocfs2_mount(struct file_system_type *fs_type, +static int ocfs2_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, - void *data) + void *data, + struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, ocfs2_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, ocfs2_fill_super, + mnt); } static void ocfs2_kill_sb(struct super_block *sb) @@ -1265,7 +1267,8 @@ static void ocfs2_kill_sb(struct super_block *sb) static struct file_system_type ocfs2_fs_type = { .owner = THIS_MODULE, .name = "ocfs2", - .mount = ocfs2_mount, + .get_sb = ocfs2_get_sb, /* is this called when we mount + * the fs? */ .kill_sb = ocfs2_kill_sb, .fs_flags = FS_REQUIRES_DEV|FS_RENAME_DOES_D_MOVE, diff --git a/trunk/fs/omfs/inode.c b/trunk/fs/omfs/inode.c index e043c4cb9a97..14a22863291a 100644 --- a/trunk/fs/omfs/inode.c +++ b/trunk/fs/omfs/inode.c @@ -557,16 +557,17 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent) return ret; } -static struct dentry *omfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int omfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, + void *data, struct vfsmount *m) { - return mount_bdev(fs_type, flags, dev_name, data, omfs_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, omfs_fill_super, m); } static struct file_system_type omfs_fs_type = { .owner = THIS_MODULE, .name = "omfs", - .mount = omfs_mount, + .get_sb = omfs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/open.c b/trunk/fs/open.c index 4197b9ed023d..d74e1983e8dc 100644 --- a/trunk/fs/open.c +++ b/trunk/fs/open.c @@ -786,11 +786,11 @@ struct file *nameidata_to_filp(struct nameidata *nd) /* Pick up the filp from the open intent */ filp = nd->intent.open.file; /* Has the filesystem initialised the file for us? */ - if (filp->f_path.dentry == NULL) { - path_get(&nd->path); + if (filp->f_path.dentry == NULL) filp = __dentry_open(nd->path.dentry, nd->path.mnt, filp, NULL, cred); - } + else + path_put(&nd->path); return filp; } diff --git a/trunk/fs/openpromfs/inode.c b/trunk/fs/openpromfs/inode.c index ddb1f41376e5..ffcd04f0012c 100644 --- a/trunk/fs/openpromfs/inode.c +++ b/trunk/fs/openpromfs/inode.c @@ -415,16 +415,16 @@ static int openprom_fill_super(struct super_block *s, void *data, int silent) return ret; } -static struct dentry *openprom_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int openprom_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_single(fs_type, flags, data, openprom_fill_super) + return get_sb_single(fs_type, flags, data, openprom_fill_super, mnt); } static struct file_system_type openprom_fs_type = { .owner = THIS_MODULE, .name = "openpromfs", - .mount = openprom_mount, + .get_sb = openprom_get_sb, .kill_sb = kill_anon_super, }; diff --git a/trunk/fs/pipe.c b/trunk/fs/pipe.c index a8012a955720..d2d7566ce68e 100644 --- a/trunk/fs/pipe.c +++ b/trunk/fs/pipe.c @@ -1247,15 +1247,16 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) * any operations on the root directory. However, we need a non-trivial * d_name - pipe: will go nicely and kill the special-casing in procfs. */ -static struct dentry *pipefs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int pipefs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, + struct vfsmount *mnt) { - return mount_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC); + return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC, mnt); } static struct file_system_type pipe_fs_type = { .name = "pipefs", - .mount = pipefs_mount, + .get_sb = pipefs_get_sb, .kill_sb = kill_anon_super, }; diff --git a/trunk/fs/proc/root.c b/trunk/fs/proc/root.c index ef9fa8e24ad6..93d99b316325 100644 --- a/trunk/fs/proc/root.c +++ b/trunk/fs/proc/root.c @@ -35,8 +35,8 @@ static int proc_set_super(struct super_block *sb, void *data) return set_anon_super(sb, NULL); } -static struct dentry *proc_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int proc_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { int err; struct super_block *sb; @@ -61,14 +61,14 @@ static struct dentry *proc_mount(struct file_system_type *fs_type, sb = sget(fs_type, proc_test_super, proc_set_super, ns); if (IS_ERR(sb)) - return ERR_CAST(sb); + return PTR_ERR(sb); if (!sb->s_root) { sb->s_flags = flags; err = proc_fill_super(sb); if (err) { deactivate_locked_super(sb); - return ERR_PTR(err); + return err; } ei = PROC_I(sb->s_root->d_inode); @@ -79,9 +79,11 @@ static struct dentry *proc_mount(struct file_system_type *fs_type, } sb->s_flags |= MS_ACTIVE; + ns->proc_mnt = mnt; } - return dget(sb->s_root); + simple_set_mnt(mnt, sb); + return 0; } static void proc_kill_sb(struct super_block *sb) @@ -95,7 +97,7 @@ static void proc_kill_sb(struct super_block *sb) static struct file_system_type proc_fs_type = { .name = "proc", - .mount = proc_mount, + .get_sb = proc_get_sb, .kill_sb = proc_kill_sb, }; @@ -113,7 +115,6 @@ void __init proc_root_init(void) return; } - init_pid_ns.proc_mnt = proc_mnt; proc_symlink("mounts", NULL, "self/mounts"); proc_net_init(); @@ -212,7 +213,6 @@ int pid_ns_prepare_proc(struct pid_namespace *ns) if (IS_ERR(mnt)) return PTR_ERR(mnt); - ns->proc_mnt = mnt; return 0; } diff --git a/trunk/fs/qnx4/inode.c b/trunk/fs/qnx4/inode.c index fcada42f1aa3..01bad30026fc 100644 --- a/trunk/fs/qnx4/inode.c +++ b/trunk/fs/qnx4/inode.c @@ -454,16 +454,17 @@ static void destroy_inodecache(void) kmem_cache_destroy(qnx4_inode_cachep); } -static struct dentry *qnx4_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int qnx4_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, qnx4_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, qnx4_fill_super, + mnt); } static struct file_system_type qnx4_fs_type = { .owner = THIS_MODULE, .name = "qnx4", - .mount = qnx4_mount, + .get_sb = qnx4_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/ramfs/inode.c b/trunk/fs/ramfs/inode.c index eacb166fb259..67fadb1ad2c1 100644 --- a/trunk/fs/ramfs/inode.c +++ b/trunk/fs/ramfs/inode.c @@ -255,16 +255,17 @@ int ramfs_fill_super(struct super_block *sb, void *data, int silent) return err; } -struct dentry *ramfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +int ramfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_nodev(fs_type, flags, data, ramfs_fill_super); + return get_sb_nodev(fs_type, flags, data, ramfs_fill_super, mnt); } -static struct dentry *rootfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int rootfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super); + return get_sb_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super, + mnt); } static void ramfs_kill_sb(struct super_block *sb) @@ -275,12 +276,12 @@ static void ramfs_kill_sb(struct super_block *sb) static struct file_system_type ramfs_fs_type = { .name = "ramfs", - .mount = ramfs_mount, + .get_sb = ramfs_get_sb, .kill_sb = ramfs_kill_sb, }; static struct file_system_type rootfs_fs_type = { .name = "rootfs", - .mount = rootfs_mount, + .get_sb = rootfs_get_sb, .kill_sb = kill_litter_super, }; diff --git a/trunk/fs/read_write.c b/trunk/fs/read_write.c index 431a0ed610c8..9cd9d148105d 100644 --- a/trunk/fs/read_write.c +++ b/trunk/fs/read_write.c @@ -243,6 +243,8 @@ SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high, * them to something that fits in "int" so that others * won't have to do range checks all the time. */ +#define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK) + int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count) { struct inode *inode; @@ -582,71 +584,65 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, unsigned long nr_segs, unsigned long fast_segs, struct iovec *fast_pointer, struct iovec **ret_pointer) -{ + { unsigned long seg; - ssize_t ret; + ssize_t ret; struct iovec *iov = fast_pointer; - /* - * SuS says "The readv() function *may* fail if the iovcnt argument - * was less than or equal to 0, or greater than {IOV_MAX}. Linux has - * traditionally returned zero for zero segments, so... - */ + /* + * SuS says "The readv() function *may* fail if the iovcnt argument + * was less than or equal to 0, or greater than {IOV_MAX}. Linux has + * traditionally returned zero for zero segments, so... + */ if (nr_segs == 0) { ret = 0; - goto out; + goto out; } - /* - * First get the "struct iovec" from user memory and - * verify all the pointers - */ + /* + * First get the "struct iovec" from user memory and + * verify all the pointers + */ if (nr_segs > UIO_MAXIOV) { ret = -EINVAL; - goto out; + goto out; } if (nr_segs > fast_segs) { - iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL); + iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL); if (iov == NULL) { ret = -ENOMEM; - goto out; + goto out; } - } + } if (copy_from_user(iov, uvector, nr_segs*sizeof(*uvector))) { ret = -EFAULT; - goto out; + goto out; } - /* + /* * According to the Single Unix Specification we should return EINVAL * if an element length is < 0 when cast to ssize_t or if the * total length would overflow the ssize_t return value of the * system call. - * - * Linux caps all read/write calls to MAX_RW_COUNT, and avoids the - * overflow case. - */ + */ ret = 0; - for (seg = 0; seg < nr_segs; seg++) { - void __user *buf = iov[seg].iov_base; - ssize_t len = (ssize_t)iov[seg].iov_len; + for (seg = 0; seg < nr_segs; seg++) { + void __user *buf = iov[seg].iov_base; + ssize_t len = (ssize_t)iov[seg].iov_len; /* see if we we're about to use an invalid len or if * it's about to overflow ssize_t */ - if (len < 0) { + if (len < 0 || (ret + len < ret)) { ret = -EINVAL; - goto out; + goto out; } if (unlikely(!access_ok(vrfy_dir(type), buf, len))) { ret = -EFAULT; - goto out; - } - if (len > MAX_RW_COUNT - ret) { - len = MAX_RW_COUNT - ret; - iov[seg].iov_len = len; + goto out; } + ret += len; - } + } out: *ret_pointer = iov; return ret; diff --git a/trunk/fs/reiserfs/super.c b/trunk/fs/reiserfs/super.c index 3bf7a6457f4d..e15ff612002d 100644 --- a/trunk/fs/reiserfs/super.c +++ b/trunk/fs/reiserfs/super.c @@ -2213,11 +2213,12 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type, #endif -static struct dentry *get_super_block(struct file_system_type *fs_type, +static int get_super_block(struct file_system_type *fs_type, int flags, const char *dev_name, - void *data) + void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, reiserfs_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, reiserfs_fill_super, + mnt); } static int __init init_reiserfs_fs(void) @@ -2252,7 +2253,7 @@ static void __exit exit_reiserfs_fs(void) struct file_system_type reiserfs_fs_type = { .owner = THIS_MODULE, .name = "reiserfs", - .mount = get_super_block, + .get_sb = get_super_block, .kill_sb = reiserfs_kill_sb, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/romfs/super.c b/trunk/fs/romfs/super.c index 6647f90e55cd..268580535c92 100644 --- a/trunk/fs/romfs/super.c +++ b/trunk/fs/romfs/super.c @@ -552,19 +552,20 @@ static int romfs_fill_super(struct super_block *sb, void *data, int silent) /* * get a superblock for mounting */ -static struct dentry *romfs_mount(struct file_system_type *fs_type, +static int romfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, - void *data) + void *data, struct vfsmount *mnt) { - struct dentry *ret = ERR_PTR(-EINVAL); + int ret = -EINVAL; #ifdef CONFIG_ROMFS_ON_MTD - ret = mount_mtd(fs_type, flags, dev_name, data, romfs_fill_super); + ret = get_sb_mtd(fs_type, flags, dev_name, data, romfs_fill_super, + mnt); #endif #ifdef CONFIG_ROMFS_ON_BLOCK - if (ret == ERR_PTR(-EINVAL)) - ret = mount_bdev(fs_type, flags, dev_name, data, - romfs_fill_super); + if (ret == -EINVAL) + ret = get_sb_bdev(fs_type, flags, dev_name, data, + romfs_fill_super, mnt); #endif return ret; } @@ -591,7 +592,7 @@ static void romfs_kill_sb(struct super_block *sb) static struct file_system_type romfs_fs_type = { .owner = THIS_MODULE, .name = "romfs", - .mount = romfs_mount, + .get_sb = romfs_get_sb, .kill_sb = romfs_kill_sb, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/squashfs/super.c b/trunk/fs/squashfs/super.c index 24de30ba34c1..07a4f1156048 100644 --- a/trunk/fs/squashfs/super.c +++ b/trunk/fs/squashfs/super.c @@ -370,10 +370,12 @@ static void squashfs_put_super(struct super_block *sb) } -static struct dentry *squashfs_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *data) +static int squashfs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, + struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, squashfs_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super, + mnt); } @@ -449,7 +451,7 @@ static void squashfs_destroy_inode(struct inode *inode) static struct file_system_type squashfs_fs_type = { .owner = THIS_MODULE, .name = "squashfs", - .mount = squashfs_mount, + .get_sb = squashfs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV }; diff --git a/trunk/fs/squashfs/xattr.c b/trunk/fs/squashfs/xattr.c index 3876c36699a1..652b8541f9c6 100644 --- a/trunk/fs/squashfs/xattr.c +++ b/trunk/fs/squashfs/xattr.c @@ -158,18 +158,17 @@ static int squashfs_xattr_get(struct inode *inode, int name_index, strncmp(target, name, name_size) == 0) { /* found xattr */ if (type & SQUASHFS_XATTR_VALUE_OOL) { - __le64 xattr_val; - u64 xattr; + __le64 xattr; /* val is a reference to the real location */ err = squashfs_read_metadata(sb, &val, &start, &offset, sizeof(val)); if (err < 0) goto failed; - err = squashfs_read_metadata(sb, &xattr_val, - &start, &offset, sizeof(xattr_val)); + err = squashfs_read_metadata(sb, &xattr, &start, + &offset, sizeof(xattr)); if (err < 0) goto failed; - xattr = le64_to_cpu(xattr_val); + xattr = le64_to_cpu(xattr); start = SQUASHFS_XATTR_BLK(xattr) + msblk->xattr_table; offset = SQUASHFS_XATTR_OFFSET(xattr); diff --git a/trunk/fs/squashfs/xattr.h b/trunk/fs/squashfs/xattr.h index b634efce4bde..49fe0d719fbf 100644 --- a/trunk/fs/squashfs/xattr.h +++ b/trunk/fs/squashfs/xattr.h @@ -25,7 +25,7 @@ extern __le64 *squashfs_read_xattr_id_table(struct super_block *, u64, u64 *, int *); extern int squashfs_xattr_lookup(struct super_block *, unsigned int, int *, - unsigned int *, unsigned long long *); + int *, unsigned long long *); #else static inline __le64 *squashfs_read_xattr_id_table(struct super_block *sb, u64 start, u64 *xattr_table_start, int *xattr_ids) @@ -35,7 +35,7 @@ static inline __le64 *squashfs_read_xattr_id_table(struct super_block *sb, } static inline int squashfs_xattr_lookup(struct super_block *sb, - unsigned int index, int *count, unsigned int *size, + unsigned int index, int *count, int *size, unsigned long long *xattr) { return 0; diff --git a/trunk/fs/squashfs/xattr_id.c b/trunk/fs/squashfs/xattr_id.c index d33be5dd6c32..cfb41106098f 100644 --- a/trunk/fs/squashfs/xattr_id.c +++ b/trunk/fs/squashfs/xattr_id.c @@ -34,7 +34,6 @@ #include "squashfs_fs_sb.h" #include "squashfs_fs_i.h" #include "squashfs.h" -#include "xattr.h" /* * Map xattr id using the xattr id look up table diff --git a/trunk/fs/super.c b/trunk/fs/super.c index ca696155cd9a..b9c9869165db 100644 --- a/trunk/fs/super.c +++ b/trunk/fs/super.c @@ -715,14 +715,15 @@ static int ns_set_super(struct super_block *sb, void *data) return set_anon_super(sb, NULL); } -struct dentry *mount_ns(struct file_system_type *fs_type, int flags, - void *data, int (*fill_super)(struct super_block *, void *, int)) +int get_sb_ns(struct file_system_type *fs_type, int flags, void *data, + int (*fill_super)(struct super_block *, void *, int), + struct vfsmount *mnt) { struct super_block *sb; sb = sget(fs_type, ns_test_super, ns_set_super, data); if (IS_ERR(sb)) - return ERR_CAST(sb); + return PTR_ERR(sb); if (!sb->s_root) { int err; @@ -730,16 +731,17 @@ struct dentry *mount_ns(struct file_system_type *fs_type, int flags, err = fill_super(sb, data, flags & MS_SILENT ? 1 : 0); if (err) { deactivate_locked_super(sb); - return ERR_PTR(err); + return err; } sb->s_flags |= MS_ACTIVE; } - return dget(sb->s_root); + simple_set_mnt(mnt, sb); + return 0; } -EXPORT_SYMBOL(mount_ns); +EXPORT_SYMBOL(get_sb_ns); #ifdef CONFIG_BLOCK static int set_bdev_super(struct super_block *s, void *data) @@ -760,9 +762,10 @@ static int test_bdev_super(struct super_block *s, void *data) return (void *)s->s_bdev == data; } -struct dentry *mount_bdev(struct file_system_type *fs_type, +int get_sb_bdev(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, - int (*fill_super)(struct super_block *, void *, int)) + int (*fill_super)(struct super_block *, void *, int), + struct vfsmount *mnt) { struct block_device *bdev; struct super_block *s; @@ -774,7 +777,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, bdev = open_bdev_exclusive(dev_name, mode, fs_type); if (IS_ERR(bdev)) - return ERR_CAST(bdev); + return PTR_ERR(bdev); /* * once the super is inserted into the list by sget, s_umount @@ -826,30 +829,15 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, bdev->bd_super = s; } - return dget(s->s_root); + simple_set_mnt(mnt, s); + return 0; error_s: error = PTR_ERR(s); error_bdev: close_bdev_exclusive(bdev, mode); error: - return ERR_PTR(error); -} -EXPORT_SYMBOL(mount_bdev); - -int get_sb_bdev(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data, - int (*fill_super)(struct super_block *, void *, int), - struct vfsmount *mnt) -{ - struct dentry *root; - - root = mount_bdev(fs_type, flags, dev_name, data, fill_super); - if (IS_ERR(root)) - return PTR_ERR(root); - mnt->mnt_root = root; - mnt->mnt_sb = root->d_sb; - return 0; + return error; } EXPORT_SYMBOL(get_sb_bdev); @@ -868,42 +856,29 @@ void kill_block_super(struct super_block *sb) EXPORT_SYMBOL(kill_block_super); #endif -struct dentry *mount_nodev(struct file_system_type *fs_type, +int get_sb_nodev(struct file_system_type *fs_type, int flags, void *data, - int (*fill_super)(struct super_block *, void *, int)) + int (*fill_super)(struct super_block *, void *, int), + struct vfsmount *mnt) { int error; struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL); if (IS_ERR(s)) - return ERR_CAST(s); + return PTR_ERR(s); s->s_flags = flags; error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); if (error) { deactivate_locked_super(s); - return ERR_PTR(error); + return error; } s->s_flags |= MS_ACTIVE; - return dget(s->s_root); -} -EXPORT_SYMBOL(mount_nodev); - -int get_sb_nodev(struct file_system_type *fs_type, - int flags, void *data, - int (*fill_super)(struct super_block *, void *, int), - struct vfsmount *mnt) -{ - struct dentry *root; - - root = mount_nodev(fs_type, flags, data, fill_super); - if (IS_ERR(root)) - return PTR_ERR(root); - mnt->mnt_root = root; - mnt->mnt_sb = root->d_sb; + simple_set_mnt(mnt, s); return 0; } + EXPORT_SYMBOL(get_sb_nodev); static int compare_single(struct super_block *s, void *p) @@ -911,42 +886,29 @@ static int compare_single(struct super_block *s, void *p) return 1; } -struct dentry *mount_single(struct file_system_type *fs_type, +int get_sb_single(struct file_system_type *fs_type, int flags, void *data, - int (*fill_super)(struct super_block *, void *, int)) + int (*fill_super)(struct super_block *, void *, int), + struct vfsmount *mnt) { struct super_block *s; int error; s = sget(fs_type, compare_single, set_anon_super, NULL); if (IS_ERR(s)) - return ERR_CAST(s); + return PTR_ERR(s); if (!s->s_root) { s->s_flags = flags; error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); if (error) { deactivate_locked_super(s); - return ERR_PTR(error); + return error; } s->s_flags |= MS_ACTIVE; } else { do_remount_sb(s, flags, data, 0); } - return dget(s->s_root); -} -EXPORT_SYMBOL(mount_single); - -int get_sb_single(struct file_system_type *fs_type, - int flags, void *data, - int (*fill_super)(struct super_block *, void *, int), - struct vfsmount *mnt) -{ - struct dentry *root; - root = mount_single(fs_type, flags, data, fill_super); - if (IS_ERR(root)) - return PTR_ERR(root); - mnt->mnt_root = root; - mnt->mnt_sb = root->d_sb; + simple_set_mnt(mnt, s); return 0; } @@ -956,7 +918,6 @@ struct vfsmount * vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data) { struct vfsmount *mnt; - struct dentry *root; char *secdata = NULL; int error; @@ -981,19 +942,9 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void goto out_free_secdata; } - if (type->mount) { - root = type->mount(type, flags, name, data); - if (IS_ERR(root)) { - error = PTR_ERR(root); - goto out_free_secdata; - } - mnt->mnt_root = root; - mnt->mnt_sb = root->d_sb; - } else { - error = type->get_sb(type, flags, name, data, mnt); - if (error < 0) - goto out_free_secdata; - } + error = type->get_sb(type, flags, name, data, mnt); + if (error < 0) + goto out_free_secdata; BUG_ON(!mnt->mnt_sb); WARN_ON(!mnt->mnt_sb->s_bdi); mnt->mnt_sb->s_flags |= MS_BORN; diff --git a/trunk/fs/sysfs/mount.c b/trunk/fs/sysfs/mount.c index 266895783b47..f2af22574c50 100644 --- a/trunk/fs/sysfs/mount.c +++ b/trunk/fs/sysfs/mount.c @@ -23,7 +23,7 @@ #include "sysfs.h" -static struct vfsmount *sysfs_mnt; +static struct vfsmount *sysfs_mount; struct kmem_cache *sysfs_dir_cachep; static const struct super_operations sysfs_ops = { @@ -95,17 +95,18 @@ static int sysfs_set_super(struct super_block *sb, void *data) return error; } -static struct dentry *sysfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int sysfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { struct sysfs_super_info *info; enum kobj_ns_type type; struct super_block *sb; int error; + error = -ENOMEM; info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) - return ERR_PTR(-ENOMEM); + goto out; for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) info->ns[type] = kobj_ns_current(type); @@ -113,19 +114,24 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type, sb = sget(fs_type, sysfs_test_super, sysfs_set_super, info); if (IS_ERR(sb) || sb->s_fs_info != info) kfree(info); - if (IS_ERR(sb)) - return ERR_CAST(sb); + if (IS_ERR(sb)) { + error = PTR_ERR(sb); + goto out; + } if (!sb->s_root) { sb->s_flags = flags; error = sysfs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); if (error) { deactivate_locked_super(sb); - return ERR_PTR(error); + goto out; } sb->s_flags |= MS_ACTIVE; } - return dget(sb->s_root); + simple_set_mnt(mnt, sb); + error = 0; +out: + return error; } static void sysfs_kill_sb(struct super_block *sb) @@ -141,7 +147,7 @@ static void sysfs_kill_sb(struct super_block *sb) static struct file_system_type sysfs_fs_type = { .name = "sysfs", - .mount = sysfs_mount, + .get_sb = sysfs_get_sb, .kill_sb = sysfs_kill_sb, }; @@ -183,11 +189,11 @@ int __init sysfs_init(void) err = register_filesystem(&sysfs_fs_type); if (!err) { - sysfs_mnt = kern_mount(&sysfs_fs_type); - if (IS_ERR(sysfs_mnt)) { + sysfs_mount = kern_mount(&sysfs_fs_type); + if (IS_ERR(sysfs_mount)) { printk(KERN_ERR "sysfs: could not mount!\n"); - err = PTR_ERR(sysfs_mnt); - sysfs_mnt = NULL; + err = PTR_ERR(sysfs_mount); + sysfs_mount = NULL; unregister_filesystem(&sysfs_fs_type); goto out_err; } diff --git a/trunk/fs/sysv/super.c b/trunk/fs/sysv/super.c index 3d9c62be0c10..a0b0cda6927e 100644 --- a/trunk/fs/sysv/super.c +++ b/trunk/fs/sysv/super.c @@ -526,22 +526,23 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent) /* Every kernel module contains stuff like this. */ -static struct dentry *sysv_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int sysv_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, sysv_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, sysv_fill_super, + mnt); } -static struct dentry *v7_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int v7_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, v7_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, v7_fill_super, mnt); } static struct file_system_type sysv_fs_type = { .owner = THIS_MODULE, .name = "sysv", - .mount = sysv_mount, + .get_sb = sysv_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; @@ -549,7 +550,7 @@ static struct file_system_type sysv_fs_type = { static struct file_system_type v7_fs_type = { .owner = THIS_MODULE, .name = "v7", - .mount = v7_mount, + .get_sb = v7_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/ubifs/super.c b/trunk/fs/ubifs/super.c index 91fac54c70e3..9a47c9f0ad07 100644 --- a/trunk/fs/ubifs/super.c +++ b/trunk/fs/ubifs/super.c @@ -2038,8 +2038,8 @@ static int sb_test(struct super_block *sb, void *data) return c->vi.cdev == *dev; } -static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags, - const char *name, void *data) +static int ubifs_get_sb(struct file_system_type *fs_type, int flags, + const char *name, void *data, struct vfsmount *mnt) { struct ubi_volume_desc *ubi; struct ubi_volume_info vi; @@ -2057,7 +2057,7 @@ static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags, if (IS_ERR(ubi)) { dbg_err("cannot open \"%s\", error %d", name, (int)PTR_ERR(ubi)); - return ERR_CAST(ubi); + return PTR_ERR(ubi); } ubi_get_volume_info(ubi, &vi); @@ -2095,19 +2095,20 @@ static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags, /* 'fill_super()' opens ubi again so we must close it here */ ubi_close_volume(ubi); - return dget(sb->s_root); + simple_set_mnt(mnt, sb); + return 0; out_deact: deactivate_locked_super(sb); out_close: ubi_close_volume(ubi); - return ERR_PTR(err); + return err; } static struct file_system_type ubifs_fs_type = { .name = "ubifs", .owner = THIS_MODULE, - .mount = ubifs_mount, + .get_sb = ubifs_get_sb, .kill_sb = kill_anon_super, }; diff --git a/trunk/fs/udf/super.c b/trunk/fs/udf/super.c index 4a5c7c61836a..76f3d6d97b40 100644 --- a/trunk/fs/udf/super.c +++ b/trunk/fs/udf/super.c @@ -107,16 +107,17 @@ struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi) } /* UDF filesystem type */ -static struct dentry *udf_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int udf_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, + struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, udf_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, udf_fill_super, mnt); } static struct file_system_type udf_fstype = { .owner = THIS_MODULE, .name = "udf", - .mount = udf_mount, + .get_sb = udf_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/ufs/super.c b/trunk/fs/ufs/super.c index 2c47daed56da..6b9be90dae7d 100644 --- a/trunk/fs/ufs/super.c +++ b/trunk/fs/ufs/super.c @@ -1454,16 +1454,16 @@ static const struct super_operations ufs_super_ops = { .show_options = ufs_show_options, }; -static struct dentry *ufs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int ufs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, ufs_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, ufs_fill_super, mnt); } static struct file_system_type ufs_fs_type = { .owner = THIS_MODULE, .name = "ufs", - .mount = ufs_mount, + .get_sb = ufs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/xfs/linux-2.6/xfs_super.c b/trunk/fs/xfs/linux-2.6/xfs_super.c index 9f3a78fe6ae4..cf808782c065 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_super.c +++ b/trunk/fs/xfs/linux-2.6/xfs_super.c @@ -1609,14 +1609,16 @@ xfs_fs_fill_super( goto out_free_sb; } -STATIC struct dentry * -xfs_fs_mount( +STATIC int +xfs_fs_get_sb( struct file_system_type *fs_type, int flags, const char *dev_name, - void *data) + void *data, + struct vfsmount *mnt) { - return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super, + mnt); } static const struct super_operations xfs_super_operations = { @@ -1637,7 +1639,7 @@ static const struct super_operations xfs_super_operations = { static struct file_system_type xfs_fs_type = { .owner = THIS_MODULE, .name = "xfs", - .mount = xfs_fs_mount, + .get_sb = xfs_fs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/include/linux/dccp.h b/trunk/include/linux/dccp.h index 749f01ccd26e..7187bd8a75f6 100644 --- a/trunk/include/linux/dccp.h +++ b/trunk/include/linux/dccp.h @@ -462,8 +462,7 @@ struct dccp_ackvec; * @dccps_hc_rx_insert_options - receiver wants to add options when acking * @dccps_hc_tx_insert_options - sender wants to add options when sending * @dccps_server_timewait - server holds timewait state on close (RFC 4340, 8.3) - * @dccps_xmitlet - tasklet scheduled by the TX CCID to dequeue data packets - * @dccps_xmit_timer - used by the TX CCID to delay sending (rate-based pacing) + * @dccps_xmit_timer - timer for when CCID is not ready to send * @dccps_syn_rtt - RTT sample from Request/Response exchange (in usecs) */ struct dccp_sock { @@ -503,7 +502,6 @@ struct dccp_sock { __u8 dccps_hc_rx_insert_options:1; __u8 dccps_hc_tx_insert_options:1; __u8 dccps_server_timewait:1; - struct tasklet_struct dccps_xmitlet; struct timer_list dccps_xmit_timer; }; diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 7b7b507ffa1c..1c73b50e81ff 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -1772,8 +1772,6 @@ struct file_system_type { int fs_flags; int (*get_sb) (struct file_system_type *, int, const char *, void *, struct vfsmount *); - struct dentry *(*mount) (struct file_system_type *, int, - const char *, void *); void (*kill_sb) (struct super_block *); struct module *owner; struct file_system_type * next; @@ -1789,25 +1787,17 @@ struct file_system_type { struct lock_class_key i_alloc_sem_key; }; -extern struct dentry *mount_ns(struct file_system_type *fs_type, int flags, - void *data, int (*fill_super)(struct super_block *, void *, int)); -extern struct dentry *mount_bdev(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data, - int (*fill_super)(struct super_block *, void *, int)); +extern int get_sb_ns(struct file_system_type *fs_type, int flags, void *data, + int (*fill_super)(struct super_block *, void *, int), + struct vfsmount *mnt); extern int get_sb_bdev(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, int (*fill_super)(struct super_block *, void *, int), struct vfsmount *mnt); -extern struct dentry *mount_single(struct file_system_type *fs_type, - int flags, void *data, - int (*fill_super)(struct super_block *, void *, int)); extern int get_sb_single(struct file_system_type *fs_type, int flags, void *data, int (*fill_super)(struct super_block *, void *, int), struct vfsmount *mnt); -extern struct dentry *mount_nodev(struct file_system_type *fs_type, - int flags, void *data, - int (*fill_super)(struct super_block *, void *, int)); extern int get_sb_nodev(struct file_system_type *fs_type, int flags, void *data, int (*fill_super)(struct super_block *, void *, int), @@ -1823,8 +1813,9 @@ struct super_block *sget(struct file_system_type *type, int (*test)(struct super_block *,void *), int (*set)(struct super_block *,void *), void *data); -extern struct dentry *mount_pseudo(struct file_system_type *, char *, - const struct super_operations *ops, unsigned long); +extern int get_sb_pseudo(struct file_system_type *, char *, + const struct super_operations *ops, unsigned long, + struct vfsmount *mnt); extern void simple_set_mnt(struct vfsmount *mnt, struct super_block *sb); static inline void sb_mark_dirty(struct super_block *sb) @@ -1867,7 +1858,6 @@ extern int current_umask(void); /* /sys/fs */ extern struct kobject *fs_kobj; -#define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK) extern int rw_verify_area(int, struct file *, loff_t *, size_t); #define FLOCK_VERIFY_READ 1 diff --git a/trunk/include/linux/kgdb.h b/trunk/include/linux/kgdb.h index 092e4250a458..cc96f0f23e04 100644 --- a/trunk/include/linux/kgdb.h +++ b/trunk/include/linux/kgdb.h @@ -35,6 +35,16 @@ struct pt_regs; */ extern int kgdb_skipexception(int exception, struct pt_regs *regs); +/** + * kgdb_disable_hw_debug - (optional) Disable hardware debugging hook + * @regs: Current &struct pt_regs. + * + * This function will be called if the particular architecture must + * disable hardware debugging while it is processing gdb packets or + * handling exception. + */ +extern void kgdb_disable_hw_debug(struct pt_regs *regs); + struct tasklet_struct; struct task_struct; struct uart_port; @@ -233,8 +243,6 @@ extern void kgdb_arch_late(void); * breakpoint. * @remove_hw_breakpoint: Allow an architecture to specify how to remove a * hardware breakpoint. - * @disable_hw_break: Allow an architecture to specify how to disable - * hardware breakpoints for a single cpu. * @remove_all_hw_break: Allow an architecture to specify how to remove all * hardware breakpoints. * @correct_hw_break: Allow an architecture to specify how to correct the @@ -248,7 +256,6 @@ struct kgdb_arch { int (*remove_breakpoint)(unsigned long, char *); int (*set_hw_breakpoint)(unsigned long, int, enum kgdb_bptype); int (*remove_hw_breakpoint)(unsigned long, int, enum kgdb_bptype); - void (*disable_hw_break)(struct pt_regs *regs); void (*remove_all_hw_break)(void); void (*correct_hw_break)(void); }; diff --git a/trunk/include/linux/mtd/super.h b/trunk/include/linux/mtd/super.h index f456230f9330..4016dd6fe336 100644 --- a/trunk/include/linux/mtd/super.h +++ b/trunk/include/linux/mtd/super.h @@ -18,9 +18,10 @@ #include #include -extern struct dentry *mount_mtd(struct file_system_type *fs_type, int flags, +extern int get_sb_mtd(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, - int (*fill_super)(struct super_block *, void *, int)); + int (*fill_super)(struct super_block *, void *, int), + struct vfsmount *mnt); extern void kill_mtd_super(struct super_block *sb); diff --git a/trunk/include/linux/ramfs.h b/trunk/include/linux/ramfs.h index 3a8f0c9b2933..e7320b5e82fb 100644 --- a/trunk/include/linux/ramfs.h +++ b/trunk/include/linux/ramfs.h @@ -3,8 +3,8 @@ struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir, int mode, dev_t dev); -extern struct dentry *ramfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data); +extern int ramfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt); #ifndef CONFIG_MMU extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize); diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index f53cdf216cef..be7adb7588e5 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -1080,7 +1080,7 @@ struct sched_class { struct task_struct *task); #ifdef CONFIG_FAIR_GROUP_SCHED - void (*task_move_group) (struct task_struct *p, int on_rq); + void (*moved_group) (struct task_struct *p, int on_rq); #endif }; diff --git a/trunk/include/linux/socket.h b/trunk/include/linux/socket.h index 86b652fabf6e..5146b50202ce 100644 --- a/trunk/include/linux/socket.h +++ b/trunk/include/linux/socket.h @@ -322,7 +322,7 @@ extern int csum_partial_copy_fromiovecend(unsigned char *kdata, int offset, unsigned int len, __wsum *csump); -extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode); +extern long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode); extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len); extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata, int offset, int len); diff --git a/trunk/include/net/ip_fib.h b/trunk/include/net/ip_fib.h index 07bdb5e9e8ac..ba3666d31766 100644 --- a/trunk/include/net/ip_fib.h +++ b/trunk/include/net/ip_fib.h @@ -158,8 +158,6 @@ extern int fib_table_flush(struct fib_table *table); extern void fib_table_select_default(struct fib_table *table, const struct flowi *flp, struct fib_result *res); -extern void fib_free_table(struct fib_table *tb); - #ifndef CONFIG_IP_MULTIPLE_TABLES diff --git a/trunk/ipc/mqueue.c b/trunk/ipc/mqueue.c index 035f4399edbc..3a61ffefe884 100644 --- a/trunk/ipc/mqueue.c +++ b/trunk/ipc/mqueue.c @@ -211,13 +211,13 @@ static int mqueue_fill_super(struct super_block *sb, void *data, int silent) return error; } -static struct dentry *mqueue_mount(struct file_system_type *fs_type, +static int mqueue_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, - void *data) + void *data, struct vfsmount *mnt) { if (!(flags & MS_KERNMOUNT)) data = current->nsproxy->ipc_ns; - return mount_ns(fs_type, flags, data, mqueue_fill_super); + return get_sb_ns(fs_type, flags, data, mqueue_fill_super, mnt); } static void init_once(void *foo) @@ -1232,7 +1232,7 @@ static const struct super_operations mqueue_super_ops = { static struct file_system_type mqueue_fs_type = { .name = "mqueue", - .mount = mqueue_mount, + .get_sb = mqueue_get_sb, .kill_sb = kill_litter_super, }; diff --git a/trunk/kernel/cgroup.c b/trunk/kernel/cgroup.c index 66a416b42c18..5cf366965d0c 100644 --- a/trunk/kernel/cgroup.c +++ b/trunk/kernel/cgroup.c @@ -1460,9 +1460,9 @@ static int cgroup_get_rootdir(struct super_block *sb) return 0; } -static struct dentry *cgroup_mount(struct file_system_type *fs_type, +static int cgroup_get_sb(struct file_system_type *fs_type, int flags, const char *unused_dev_name, - void *data) + void *data, struct vfsmount *mnt) { struct cgroup_sb_opts opts; struct cgroupfs_root *root; @@ -1596,9 +1596,10 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type, drop_parsed_module_refcounts(opts.subsys_bits); } + simple_set_mnt(mnt, sb); kfree(opts.release_agent); kfree(opts.name); - return dget(sb->s_root); + return 0; drop_new_super: deactivate_locked_super(sb); @@ -1607,7 +1608,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type, out_err: kfree(opts.release_agent); kfree(opts.name); - return ERR_PTR(ret); + return ret; } static void cgroup_kill_sb(struct super_block *sb) { @@ -1657,7 +1658,7 @@ static void cgroup_kill_sb(struct super_block *sb) { static struct file_system_type cgroup_fs_type = { .name = "cgroup", - .mount = cgroup_mount, + .get_sb = cgroup_get_sb, .kill_sb = cgroup_kill_sb, }; diff --git a/trunk/kernel/cpuset.c b/trunk/kernel/cpuset.c index 4349935c2ad8..51b143e2a07a 100644 --- a/trunk/kernel/cpuset.c +++ b/trunk/kernel/cpuset.c @@ -231,17 +231,18 @@ static DEFINE_SPINLOCK(cpuset_buffer_lock); * users. If someone tries to mount the "cpuset" filesystem, we * silently switch it to mount "cgroup" instead */ -static struct dentry *cpuset_mount(struct file_system_type *fs_type, - int flags, const char *unused_dev_name, void *data) +static int cpuset_get_sb(struct file_system_type *fs_type, + int flags, const char *unused_dev_name, + void *data, struct vfsmount *mnt) { struct file_system_type *cgroup_fs = get_fs_type("cgroup"); - struct dentry *ret = ERR_PTR(-ENODEV); + int ret = -ENODEV; if (cgroup_fs) { char mountopts[] = "cpuset,noprefix," "release_agent=/sbin/cpuset_release_agent"; - ret = cgroup_fs->mount(cgroup_fs, flags, - unused_dev_name, mountopts); + ret = cgroup_fs->get_sb(cgroup_fs, flags, + unused_dev_name, mountopts, mnt); put_filesystem(cgroup_fs); } return ret; @@ -249,7 +250,7 @@ static struct dentry *cpuset_mount(struct file_system_type *fs_type, static struct file_system_type cpuset_fs_type = { .name = "cpuset", - .mount = cpuset_mount, + .get_sb = cpuset_get_sb, }; /* diff --git a/trunk/kernel/debug/debug_core.c b/trunk/kernel/debug/debug_core.c index cefd4a11f6d9..fec596da9bd0 100644 --- a/trunk/kernel/debug/debug_core.c +++ b/trunk/kernel/debug/debug_core.c @@ -209,6 +209,18 @@ int __weak kgdb_skipexception(int exception, struct pt_regs *regs) return 0; } +/** + * kgdb_disable_hw_debug - Disable hardware debugging while we in kgdb. + * @regs: Current &struct pt_regs. + * + * This function will be called if the particular architecture must + * disable hardware debugging while it is processing gdb packets or + * handling exception. + */ +void __weak kgdb_disable_hw_debug(struct pt_regs *regs) +{ +} + /* * Some architectures need cache flushes when we set/clear a * breakpoint: @@ -472,9 +484,7 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs, atomic_inc(&masters_in_kgdb); else atomic_inc(&slaves_in_kgdb); - - if (arch_kgdb_ops.disable_hw_break) - arch_kgdb_ops.disable_hw_break(regs); + kgdb_disable_hw_debug(ks->linux_regs); acquirelock: /* diff --git a/trunk/kernel/debug/kdb/kdb_main.c b/trunk/kernel/debug/kdb/kdb_main.c index 37755d621924..d7bda21a106b 100644 --- a/trunk/kernel/debug/kdb/kdb_main.c +++ b/trunk/kernel/debug/kdb/kdb_main.c @@ -1127,7 +1127,7 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, /* special case below */ } else { kdb_printf("\nEntering kdb (current=0x%p, pid %d) ", - kdb_current, kdb_current ? kdb_current->pid : 0); + kdb_current, kdb_current->pid); #if defined(CONFIG_SMP) kdb_printf("on processor %d ", raw_smp_processor_id()); #endif @@ -2603,17 +2603,20 @@ static int kdb_summary(int argc, const char **argv) */ static int kdb_per_cpu(int argc, const char **argv) { - char fmtstr[64]; - int cpu, diag, nextarg = 1; - unsigned long addr, symaddr, val, bytesperword = 0, whichcpu = ~0UL; + char buf[256], fmtstr[64]; + kdb_symtab_t symtab; + cpumask_t suppress = CPU_MASK_NONE; + int cpu, diag; + unsigned long addr, val, bytesperword = 0, whichcpu = ~0UL; if (argc < 1 || argc > 3) return KDB_ARGCOUNT; - diag = kdbgetaddrarg(argc, argv, &nextarg, &symaddr, NULL, NULL); - if (diag) - return diag; - + snprintf(buf, sizeof(buf), "per_cpu__%s", argv[1]); + if (!kdbgetsymval(buf, &symtab)) { + kdb_printf("%s is not a per_cpu variable\n", argv[1]); + return KDB_BADADDR; + } if (argc >= 2) { diag = kdbgetularg(argv[2], &bytesperword); if (diag) @@ -2646,25 +2649,46 @@ static int kdb_per_cpu(int argc, const char **argv) #define KDB_PCU(cpu) 0 #endif #endif - for_each_online_cpu(cpu) { - if (KDB_FLAG(CMD_INTERRUPT)) - return 0; + for_each_online_cpu(cpu) { if (whichcpu != ~0UL && whichcpu != cpu) continue; - addr = symaddr + KDB_PCU(cpu); + addr = symtab.sym_start + KDB_PCU(cpu); diag = kdb_getword(&val, addr, bytesperword); if (diag) { kdb_printf("%5d " kdb_bfd_vma_fmt0 " - unable to " "read, diag=%d\n", cpu, addr, diag); continue; } +#ifdef CONFIG_SMP + if (!val) { + cpu_set(cpu, suppress); + continue; + } +#endif /* CONFIG_SMP */ kdb_printf("%5d ", cpu); kdb_md_line(fmtstr, addr, bytesperword == KDB_WORD_SIZE, 1, bytesperword, 1, 1, 0); } + if (cpus_weight(suppress) == 0) + return 0; + kdb_printf("Zero suppressed cpu(s):"); + for (cpu = first_cpu(suppress); cpu < num_possible_cpus(); + cpu = next_cpu(cpu, suppress)) { + kdb_printf(" %d", cpu); + if (cpu == num_possible_cpus() - 1 || + next_cpu(cpu, suppress) != cpu + 1) + continue; + while (cpu < num_possible_cpus() && + next_cpu(cpu, suppress) == cpu + 1) + ++cpu; + kdb_printf("-%d", cpu); + } + kdb_printf("\n"); + #undef KDB_PCU + return 0; } diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index aa14a56f9d03..d42992bccdfa 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -8510,12 +8510,12 @@ void sched_move_task(struct task_struct *tsk) if (unlikely(running)) tsk->sched_class->put_prev_task(rq, tsk); + set_task_rq(tsk, task_cpu(tsk)); + #ifdef CONFIG_FAIR_GROUP_SCHED - if (tsk->sched_class->task_move_group) - tsk->sched_class->task_move_group(tsk, on_rq); - else + if (tsk->sched_class->moved_group) + tsk->sched_class->moved_group(tsk, on_rq); #endif - set_task_rq(tsk, task_cpu(tsk)); if (unlikely(running)) tsk->sched_class->set_curr_task(rq); diff --git a/trunk/kernel/sched_fair.c b/trunk/kernel/sched_fair.c index f4f6a8326dd0..933f3d1b62ea 100644 --- a/trunk/kernel/sched_fair.c +++ b/trunk/kernel/sched_fair.c @@ -3869,26 +3869,13 @@ static void set_curr_task_fair(struct rq *rq) } #ifdef CONFIG_FAIR_GROUP_SCHED -static void task_move_group_fair(struct task_struct *p, int on_rq) +static void moved_group_fair(struct task_struct *p, int on_rq) { - /* - * If the task was not on the rq at the time of this cgroup movement - * it must have been asleep, sleeping tasks keep their ->vruntime - * absolute on their old rq until wakeup (needed for the fair sleeper - * bonus in place_entity()). - * - * If it was on the rq, we've just 'preempted' it, which does convert - * ->vruntime to a relative base. - * - * Make sure both cases convert their relative position when migrating - * to another cgroup's rq. This does somewhat interfere with the - * fair sleeper stuff for the first placement, but who cares. - */ - if (!on_rq) - p->se.vruntime -= cfs_rq_of(&p->se)->min_vruntime; - set_task_rq(p, task_cpu(p)); + struct cfs_rq *cfs_rq = task_cfs_rq(p); + + update_curr(cfs_rq); if (!on_rq) - p->se.vruntime += cfs_rq_of(&p->se)->min_vruntime; + place_entity(cfs_rq, &p->se, 1); } #endif @@ -3940,7 +3927,7 @@ static const struct sched_class fair_sched_class = { .get_rr_interval = get_rr_interval_fair, #ifdef CONFIG_FAIR_GROUP_SCHED - .task_move_group = task_move_group_fair, + .moved_group = moved_group_fair, #endif }; diff --git a/trunk/kernel/sched_stats.h b/trunk/kernel/sched_stats.h index 48ddf431db0e..25c2f962f6fc 100644 --- a/trunk/kernel/sched_stats.h +++ b/trunk/kernel/sched_stats.h @@ -157,7 +157,15 @@ static inline void sched_info_reset_dequeued(struct task_struct *t) } /* - * We are interested in knowing how long it was from the *first* time a + * Called when a process is dequeued from the active array and given + * the cpu. We should note that with the exception of interactive + * tasks, the expired queue will become the active queue after the active + * queue is empty, without explicitly dequeuing and requeuing tasks in the + * expired queue. (Interactive tasks may be requeued directly to the + * active queue, thus delaying tasks in the expired queue from running; + * see scheduler_tick()). + * + * Though we are interested in knowing how long it was from the *first* time a * task was queued to the time that it finally hit a cpu, we call this routine * from dequeue_task() to account for possible rq->clock skew across cpus. The * delta taken on each cpu would annul the skew. @@ -195,6 +203,16 @@ static void sched_info_arrive(struct task_struct *t) } /* + * Called when a process is queued into either the active or expired + * array. The time is noted and later used to determine how long we + * had to wait for us to reach the cpu. Since the expired queue will + * become the active queue after active queue is empty, without dequeuing + * and requeuing any tasks, we are interested in queuing to either. It + * is unusual but not impossible for tasks to be dequeued and immediately + * requeued in the same or another array: this can happen in sched_yield(), + * set_user_nice(), and even load_balance() as it moves tasks from runqueue + * to runqueue. + * * This function is only called from enqueue_task(), but also only updates * the timestamp if it is already not set. It's assumed that * sched_info_dequeued() will clear that stamp when appropriate. diff --git a/trunk/mm/shmem.c b/trunk/mm/shmem.c index 47fdeeb9d636..f6d350e8adc5 100644 --- a/trunk/mm/shmem.c +++ b/trunk/mm/shmem.c @@ -2538,16 +2538,16 @@ static const struct vm_operations_struct shmem_vm_ops = { }; -static struct dentry *shmem_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int shmem_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_nodev(fs_type, flags, data, shmem_fill_super); + return get_sb_nodev(fs_type, flags, data, shmem_fill_super, mnt); } static struct file_system_type tmpfs_fs_type = { .owner = THIS_MODULE, .name = "tmpfs", - .mount = shmem_mount, + .get_sb = shmem_get_sb, .kill_sb = kill_litter_super, }; @@ -2643,7 +2643,7 @@ void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff, static struct file_system_type tmpfs_fs_type = { .name = "tmpfs", - .mount = ramfs_mount, + .get_sb = ramfs_get_sb, .kill_sb = kill_litter_super, }; diff --git a/trunk/net/compat.c b/trunk/net/compat.c index 3649d5895361..63d260e81472 100644 --- a/trunk/net/compat.c +++ b/trunk/net/compat.c @@ -41,12 +41,10 @@ static inline int iov_from_user_compat_to_kern(struct iovec *kiov, compat_size_t len; if (get_user(len, &uiov32->iov_len) || - get_user(buf, &uiov32->iov_base)) - return -EFAULT; - - if (len > INT_MAX - tot_len) - len = INT_MAX - tot_len; - + get_user(buf, &uiov32->iov_base)) { + tot_len = -EFAULT; + break; + } tot_len += len; kiov->iov_base = compat_ptr(buf); kiov->iov_len = (__kernel_size_t) len; diff --git a/trunk/net/core/iovec.c b/trunk/net/core/iovec.c index c40f27e7d208..72aceb1fe4fa 100644 --- a/trunk/net/core/iovec.c +++ b/trunk/net/core/iovec.c @@ -35,9 +35,10 @@ * in any case. */ -int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode) +long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode) { - int size, ct, err; + int size, ct; + long err; if (m->msg_namelen) { if (mode == VERIFY_READ) { @@ -61,13 +62,14 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, err = 0; for (ct = 0; ct < m->msg_iovlen; ct++) { - size_t len = iov[ct].iov_len; - - if (len > INT_MAX - err) { - len = INT_MAX - err; - iov[ct].iov_len = len; - } - err += len; + err += iov[ct].iov_len; + /* + * Goal is not to verify user data, but to prevent returning + * negative value, which is interpreted as errno. + * Overflow is still possible, but it is harmless. + */ + if (err < 0) + return -EMSGSIZE; } return err; diff --git a/trunk/net/core/pktgen.c b/trunk/net/core/pktgen.c index fbce4b05a53e..679b797d06b1 100644 --- a/trunk/net/core/pktgen.c +++ b/trunk/net/core/pktgen.c @@ -887,11 +887,10 @@ static ssize_t pktgen_if_write(struct file *file, i += len; if (debug) { - size_t copy = min(count, 1023); - char tb[copy + 1]; - if (copy_from_user(tb, user_buffer, copy)) + char tb[count + 1]; + if (copy_from_user(tb, user_buffer, count)) return -EFAULT; - tb[copy] = 0; + tb[count] = 0; printk(KERN_DEBUG "pktgen: %s,%lu buffer -:%s:-\n", name, (unsigned long)count, tb); } diff --git a/trunk/net/dccp/ccid.h b/trunk/net/dccp/ccid.h index 75c3582a7678..117fb093dcaf 100644 --- a/trunk/net/dccp/ccid.h +++ b/trunk/net/dccp/ccid.h @@ -134,41 +134,13 @@ static inline int ccid_get_current_tx_ccid(struct dccp_sock *dp) extern void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk); extern void ccid_hc_tx_delete(struct ccid *ccid, struct sock *sk); -/* - * Congestion control of queued data packets via CCID decision. - * - * The TX CCID performs its congestion-control by indicating whether and when a - * queued packet may be sent, using the return code of ccid_hc_tx_send_packet(). - * The following modes are supported via the symbolic constants below: - * - timer-based pacing (CCID returns a delay value in milliseconds); - * - autonomous dequeueing (CCID internally schedules dccps_xmitlet). - */ - -enum ccid_dequeueing_decision { - CCID_PACKET_SEND_AT_ONCE = 0x00000, /* "green light": no delay */ - CCID_PACKET_DELAY_MAX = 0x0FFFF, /* maximum delay in msecs */ - CCID_PACKET_DELAY = 0x10000, /* CCID msec-delay mode */ - CCID_PACKET_WILL_DEQUEUE_LATER = 0x20000, /* CCID autonomous mode */ - CCID_PACKET_ERR = 0xF0000, /* error condition */ -}; - -static inline int ccid_packet_dequeue_eval(const int return_code) -{ - if (return_code < 0) - return CCID_PACKET_ERR; - if (return_code == 0) - return CCID_PACKET_SEND_AT_ONCE; - if (return_code <= CCID_PACKET_DELAY_MAX) - return CCID_PACKET_DELAY; - return return_code; -} - static inline int ccid_hc_tx_send_packet(struct ccid *ccid, struct sock *sk, struct sk_buff *skb) { + int rc = 0; if (ccid->ccid_ops->ccid_hc_tx_send_packet != NULL) - return ccid->ccid_ops->ccid_hc_tx_send_packet(sk, skb); - return CCID_PACKET_SEND_AT_ONCE; + rc = ccid->ccid_ops->ccid_hc_tx_send_packet(sk, skb); + return rc; } static inline void ccid_hc_tx_packet_sent(struct ccid *ccid, struct sock *sk, diff --git a/trunk/net/dccp/ccids/ccid2.c b/trunk/net/dccp/ccids/ccid2.c index 6576eae9e779..d850e291f87c 100644 --- a/trunk/net/dccp/ccids/ccid2.c +++ b/trunk/net/dccp/ccids/ccid2.c @@ -78,9 +78,12 @@ static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hc) static int ccid2_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) { - if (ccid2_cwnd_network_limited(ccid2_hc_tx_sk(sk))) - return CCID_PACKET_WILL_DEQUEUE_LATER; - return CCID_PACKET_SEND_AT_ONCE; + struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); + + if (hc->tx_pipe < hc->tx_cwnd) + return 0; + + return 1; /* XXX CCID should dequeue when ready instead of polling */ } static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val) @@ -112,7 +115,6 @@ static void ccid2_hc_tx_rto_expire(unsigned long data) { struct sock *sk = (struct sock *)data; struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); - const bool sender_was_blocked = ccid2_cwnd_network_limited(hc); bh_lock_sock(sk); if (sock_owned_by_user(sk)) { @@ -127,6 +129,8 @@ static void ccid2_hc_tx_rto_expire(unsigned long data) if (hc->tx_rto > DCCP_RTO_MAX) hc->tx_rto = DCCP_RTO_MAX; + sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); + /* adjust pipe, cwnd etc */ hc->tx_ssthresh = hc->tx_cwnd / 2; if (hc->tx_ssthresh < 2) @@ -142,12 +146,6 @@ static void ccid2_hc_tx_rto_expire(unsigned long data) hc->tx_rpseq = 0; hc->tx_rpdupack = -1; ccid2_change_l_ack_ratio(sk, 1); - - /* if we were blocked before, we may now send cwnd=1 packet */ - if (sender_was_blocked) - tasklet_schedule(&dccp_sk(sk)->dccps_xmitlet); - /* restart backed-off timer */ - sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); out: bh_unlock_sock(sk); sock_put(sk); @@ -436,7 +434,6 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) { struct dccp_sock *dp = dccp_sk(sk); struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); - const bool sender_was_blocked = ccid2_cwnd_network_limited(hc); u64 ackno, seqno; struct ccid2_seq *seqp; unsigned char *vector; @@ -634,10 +631,6 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) sk_stop_timer(sk, &hc->tx_rtotimer); else sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); - - /* check if incoming Acks allow pending packets to be sent */ - if (sender_was_blocked && !ccid2_cwnd_network_limited(hc)) - tasklet_schedule(&dccp_sk(sk)->dccps_xmitlet); } static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) diff --git a/trunk/net/dccp/ccids/ccid2.h b/trunk/net/dccp/ccids/ccid2.h index 25cb6b216eda..9731c2dc1487 100644 --- a/trunk/net/dccp/ccids/ccid2.h +++ b/trunk/net/dccp/ccids/ccid2.h @@ -81,11 +81,6 @@ struct ccid2_hc_tx_sock { u64 tx_high_ack; }; -static inline bool ccid2_cwnd_network_limited(struct ccid2_hc_tx_sock *hc) -{ - return hc->tx_pipe >= hc->tx_cwnd; -} - struct ccid2_hc_rx_sock { int rx_data; }; diff --git a/trunk/net/dccp/ccids/ccid3.c b/trunk/net/dccp/ccids/ccid3.c index 3d604e1349c0..3060a60ed5ab 100644 --- a/trunk/net/dccp/ccids/ccid3.c +++ b/trunk/net/dccp/ccids/ccid3.c @@ -268,11 +268,11 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data) sock_put(sk); } -/** - * ccid3_hc_tx_send_packet - Delay-based dequeueing of TX packets - * @skb: next packet candidate to send on @sk - * This function uses the convention of ccid_packet_dequeue_eval() and - * returns a millisecond-delay value between 0 and t_mbi = 64000 msec. +/* + * returns + * > 0: delay (in msecs) that should pass before actually sending + * = 0: can send immediately + * < 0: error condition; do not send packet */ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) { @@ -348,7 +348,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) /* set the nominal send time for the next following packet */ hc->tx_t_nom = ktime_add_us(hc->tx_t_nom, hc->tx_t_ipi); - return CCID_PACKET_SEND_AT_ONCE; + return 0; } static void ccid3_hc_tx_packet_sent(struct sock *sk, unsigned int len) diff --git a/trunk/net/dccp/dccp.h b/trunk/net/dccp/dccp.h index a8ed459508b2..3eb264b60823 100644 --- a/trunk/net/dccp/dccp.h +++ b/trunk/net/dccp/dccp.h @@ -243,9 +243,8 @@ extern void dccp_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, extern void dccp_send_sync(struct sock *sk, const u64 seq, const enum dccp_pkt_type pkt_type); -extern void dccp_write_xmit(struct sock *sk); -extern void dccp_write_space(struct sock *sk); -extern void dccp_flush_write_queue(struct sock *sk, long *time_budget); +extern void dccp_write_xmit(struct sock *sk, int block); +extern void dccp_write_space(struct sock *sk); extern void dccp_init_xmit_timers(struct sock *sk); static inline void dccp_clear_xmit_timers(struct sock *sk) diff --git a/trunk/net/dccp/output.c b/trunk/net/dccp/output.c index 45b91853f5ae..a988fe9ffcba 100644 --- a/trunk/net/dccp/output.c +++ b/trunk/net/dccp/output.c @@ -209,150 +209,108 @@ void dccp_write_space(struct sock *sk) } /** - * dccp_wait_for_ccid - Await CCID send permission + * dccp_wait_for_ccid - Wait for ccid to tell us we can send a packet * @sk: socket to wait for - * @delay: timeout in jiffies - * This is used by CCIDs which need to delay the send time in process context. + * @skb: current skb to pass on for waiting + * @delay: sleep timeout in milliseconds (> 0) + * This function is called by default when the socket is closed, and + * when a non-zero linger time is set on the socket. For consistency */ -static int dccp_wait_for_ccid(struct sock *sk, unsigned long delay) +static int dccp_wait_for_ccid(struct sock *sk, struct sk_buff *skb, int delay) { - DEFINE_WAIT(wait); - long remaining; - - prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); - sk->sk_write_pending++; - release_sock(sk); - - remaining = schedule_timeout(delay); - - lock_sock(sk); - sk->sk_write_pending--; - finish_wait(sk_sleep(sk), &wait); - - if (signal_pending(current) || sk->sk_err) - return -1; - return remaining; -} - -/** - * dccp_xmit_packet - Send data packet under control of CCID - * Transmits next-queued payload and informs CCID to account for the packet. - */ -static void dccp_xmit_packet(struct sock *sk) -{ - int err, len; struct dccp_sock *dp = dccp_sk(sk); - struct sk_buff *skb = skb_dequeue(&sk->sk_write_queue); + DEFINE_WAIT(wait); + unsigned long jiffdelay; + int rc; - if (unlikely(skb == NULL)) - return; - len = skb->len; + do { + dccp_pr_debug("delayed send by %d msec\n", delay); + jiffdelay = msecs_to_jiffies(delay); - if (sk->sk_state == DCCP_PARTOPEN) { - const u32 cur_mps = dp->dccps_mss_cache - DCCP_FEATNEG_OVERHEAD; - /* - * See 8.1.5 - Handshake Completion. - * - * For robustness we resend Confirm options until the client has - * entered OPEN. During the initial feature negotiation, the MPS - * is smaller than usual, reduced by the Change/Confirm options. - */ - if (!list_empty(&dp->dccps_featneg) && len > cur_mps) { - DCCP_WARN("Payload too large (%d) for featneg.\n", len); - dccp_send_ack(sk); - dccp_feat_list_purge(&dp->dccps_featneg); - } + prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); - inet_csk_schedule_ack(sk); - inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, - inet_csk(sk)->icsk_rto, - DCCP_RTO_MAX); - DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATAACK; - } else if (dccp_ack_pending(sk)) { - DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATAACK; - } else { - DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATA; - } - - err = dccp_transmit_skb(sk, skb); - if (err) - dccp_pr_debug("transmit_skb() returned err=%d\n", err); - /* - * Register this one as sent even if an error occurred. To the remote - * end a local packet drop is indistinguishable from network loss, i.e. - * any local drop will eventually be reported via receiver feedback. - */ - ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len); -} + sk->sk_write_pending++; + release_sock(sk); + schedule_timeout(jiffdelay); + lock_sock(sk); + sk->sk_write_pending--; -/** - * dccp_flush_write_queue - Drain queue at end of connection - * Since dccp_sendmsg queues packets without waiting for them to be sent, it may - * happen that the TX queue is not empty at the end of a connection. We give the - * HC-sender CCID a grace period of up to @time_budget jiffies. If this function - * returns with a non-empty write queue, it will be purged later. - */ -void dccp_flush_write_queue(struct sock *sk, long *time_budget) -{ - struct dccp_sock *dp = dccp_sk(sk); - struct sk_buff *skb; - long delay, rc; + if (sk->sk_err) + goto do_error; + if (signal_pending(current)) + goto do_interrupted; - while (*time_budget > 0 && (skb = skb_peek(&sk->sk_write_queue))) { rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb); - - switch (ccid_packet_dequeue_eval(rc)) { - case CCID_PACKET_WILL_DEQUEUE_LATER: - /* - * If the CCID determines when to send, the next sending - * time is unknown or the CCID may not even send again - * (e.g. remote host crashes or lost Ack packets). - */ - DCCP_WARN("CCID did not manage to send all packets\n"); - return; - case CCID_PACKET_DELAY: - delay = msecs_to_jiffies(rc); - if (delay > *time_budget) - return; - rc = dccp_wait_for_ccid(sk, delay); - if (rc < 0) - return; - *time_budget -= (delay - rc); - /* check again if we can send now */ - break; - case CCID_PACKET_SEND_AT_ONCE: - dccp_xmit_packet(sk); - break; - case CCID_PACKET_ERR: - skb_dequeue(&sk->sk_write_queue); - kfree_skb(skb); - dccp_pr_debug("packet discarded due to err=%ld\n", rc); - } - } + } while ((delay = rc) > 0); +out: + finish_wait(sk_sleep(sk), &wait); + return rc; + +do_error: + rc = -EPIPE; + goto out; +do_interrupted: + rc = -EINTR; + goto out; } -void dccp_write_xmit(struct sock *sk) +void dccp_write_xmit(struct sock *sk, int block) { struct dccp_sock *dp = dccp_sk(sk); struct sk_buff *skb; while ((skb = skb_peek(&sk->sk_write_queue))) { - int rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb); + int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb); + + if (err > 0) { + if (!block) { + sk_reset_timer(sk, &dp->dccps_xmit_timer, + msecs_to_jiffies(err)+jiffies); + break; + } else + err = dccp_wait_for_ccid(sk, skb, err); + if (err && err != -EINTR) + DCCP_BUG("err=%d after dccp_wait_for_ccid", err); + } - switch (ccid_packet_dequeue_eval(rc)) { - case CCID_PACKET_WILL_DEQUEUE_LATER: - return; - case CCID_PACKET_DELAY: - sk_reset_timer(sk, &dp->dccps_xmit_timer, - jiffies + msecs_to_jiffies(rc)); - return; - case CCID_PACKET_SEND_AT_ONCE: - dccp_xmit_packet(sk); - break; - case CCID_PACKET_ERR: - skb_dequeue(&sk->sk_write_queue); + skb_dequeue(&sk->sk_write_queue); + if (err == 0) { + struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); + const int len = skb->len; + + if (sk->sk_state == DCCP_PARTOPEN) { + const u32 cur_mps = dp->dccps_mss_cache - DCCP_FEATNEG_OVERHEAD; + /* + * See 8.1.5 - Handshake Completion. + * + * For robustness we resend Confirm options until the client has + * entered OPEN. During the initial feature negotiation, the MPS + * is smaller than usual, reduced by the Change/Confirm options. + */ + if (!list_empty(&dp->dccps_featneg) && len > cur_mps) { + DCCP_WARN("Payload too large (%d) for featneg.\n", len); + dccp_send_ack(sk); + dccp_feat_list_purge(&dp->dccps_featneg); + } + + inet_csk_schedule_ack(sk); + inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, + inet_csk(sk)->icsk_rto, + DCCP_RTO_MAX); + dcb->dccpd_type = DCCP_PKT_DATAACK; + } else if (dccp_ack_pending(sk)) + dcb->dccpd_type = DCCP_PKT_DATAACK; + else + dcb->dccpd_type = DCCP_PKT_DATA; + + err = dccp_transmit_skb(sk, skb); + ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len); + if (err) + DCCP_BUG("err=%d after ccid_hc_tx_packet_sent", + err); + } else { + dccp_pr_debug("packet discarded due to err=%d\n", err); kfree_skb(skb); - dccp_pr_debug("packet discarded due to err=%d\n", rc); } } } @@ -664,6 +622,7 @@ void dccp_send_close(struct sock *sk, const int active) DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSE; if (active) { + dccp_write_xmit(sk, 1); dccp_skb_entail(sk, skb); dccp_transmit_skb(sk, skb_clone(skb, prio)); /* diff --git a/trunk/net/dccp/proto.c b/trunk/net/dccp/proto.c index ef343d53fcea..7e5fc04eb6d1 100644 --- a/trunk/net/dccp/proto.c +++ b/trunk/net/dccp/proto.c @@ -726,13 +726,7 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto out_discard; skb_queue_tail(&sk->sk_write_queue, skb); - /* - * The xmit_timer is set if the TX CCID is rate-based and will expire - * when congestion control permits to release further packets into the - * network. Window-based CCIDs do not use this timer. - */ - if (!timer_pending(&dp->dccps_xmit_timer)) - dccp_write_xmit(sk); + dccp_write_xmit(sk,0); out_release: release_sock(sk); return rc ? : len; @@ -957,22 +951,9 @@ void dccp_close(struct sock *sk, long timeout) /* Check zero linger _after_ checking for unread data. */ sk->sk_prot->disconnect(sk, 0); } else if (sk->sk_state != DCCP_CLOSED) { - /* - * Normal connection termination. May need to wait if there are - * still packets in the TX queue that are delayed by the CCID. - */ - dccp_flush_write_queue(sk, &timeout); dccp_terminate_connection(sk); } - /* - * Flush write queue. This may be necessary in several cases: - * - we have been closed by the peer but still have application data; - * - abortive termination (unread data or zero linger time), - * - normal termination but queue could not be flushed within time limit - */ - __skb_queue_purge(&sk->sk_write_queue); - sk_stream_wait_close(sk, timeout); adjudge_to_death: diff --git a/trunk/net/dccp/timer.c b/trunk/net/dccp/timer.c index 7587870b7040..1a9aa05d4dc4 100644 --- a/trunk/net/dccp/timer.c +++ b/trunk/net/dccp/timer.c @@ -237,35 +237,32 @@ static void dccp_delack_timer(unsigned long data) sock_put(sk); } -/** - * dccp_write_xmitlet - Workhorse for CCID packet dequeueing interface - * See the comments above %ccid_dequeueing_decision for supported modes. - */ -static void dccp_write_xmitlet(unsigned long data) +/* Transmit-delay timer: used by the CCIDs to delay actual send time */ +static void dccp_write_xmit_timer(unsigned long data) { struct sock *sk = (struct sock *)data; + struct dccp_sock *dp = dccp_sk(sk); bh_lock_sock(sk); if (sock_owned_by_user(sk)) - sk_reset_timer(sk, &dccp_sk(sk)->dccps_xmit_timer, jiffies + 1); + sk_reset_timer(sk, &dp->dccps_xmit_timer, jiffies+1); else - dccp_write_xmit(sk); + dccp_write_xmit(sk, 0); bh_unlock_sock(sk); + sock_put(sk); } -static void dccp_write_xmit_timer(unsigned long data) +static void dccp_init_write_xmit_timer(struct sock *sk) { - dccp_write_xmitlet(data); - sock_put((struct sock *)data); + struct dccp_sock *dp = dccp_sk(sk); + + setup_timer(&dp->dccps_xmit_timer, dccp_write_xmit_timer, + (unsigned long)sk); } void dccp_init_xmit_timers(struct sock *sk) { - struct dccp_sock *dp = dccp_sk(sk); - - tasklet_init(&dp->dccps_xmitlet, dccp_write_xmitlet, (unsigned long)sk); - setup_timer(&dp->dccps_xmit_timer, dccp_write_xmit_timer, - (unsigned long)sk); + dccp_init_write_xmit_timer(sk); inet_csk_init_xmit_timers(sk, &dccp_write_timer, &dccp_delack_timer, &dccp_keepalive_timer); } diff --git a/trunk/net/ipv4/fib_frontend.c b/trunk/net/ipv4/fib_frontend.c index eb6f69a8f27a..36e27c2107de 100644 --- a/trunk/net/ipv4/fib_frontend.c +++ b/trunk/net/ipv4/fib_frontend.c @@ -1052,7 +1052,7 @@ static void ip_fib_net_exit(struct net *net) hlist_for_each_entry_safe(tb, node, tmp, head, tb_hlist) { hlist_del(node); fib_table_flush(tb); - fib_free_table(tb); + kfree(tb); } } kfree(net->ipv4.fib_table_hash); diff --git a/trunk/net/ipv4/fib_hash.c b/trunk/net/ipv4/fib_hash.c index b3acb0417b21..b232375a0b75 100644 --- a/trunk/net/ipv4/fib_hash.c +++ b/trunk/net/ipv4/fib_hash.c @@ -716,24 +716,6 @@ int fib_table_flush(struct fib_table *tb) return found; } -void fib_free_table(struct fib_table *tb) -{ - struct fn_hash *table = (struct fn_hash *) tb->tb_data; - struct fn_zone *fz, *next; - - next = table->fn_zone_list; - while (next != NULL) { - fz = next; - next = fz->fz_next; - - if (fz->fz_hash != fz->fz_embedded_hash) - fz_hash_free(fz->fz_hash, fz->fz_divisor); - - kfree(fz); - } - - kfree(tb); -} static inline int fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb, diff --git a/trunk/net/ipv4/fib_trie.c b/trunk/net/ipv4/fib_trie.c index 200eb538fbb3..b14450895102 100644 --- a/trunk/net/ipv4/fib_trie.c +++ b/trunk/net/ipv4/fib_trie.c @@ -1797,11 +1797,6 @@ int fib_table_flush(struct fib_table *tb) return found; } -void fib_free_table(struct fib_table *tb) -{ - kfree(tb); -} - void fib_table_select_default(struct fib_table *tb, const struct flowi *flp, struct fib_result *res) diff --git a/trunk/net/mac80211/debugfs_key.c b/trunk/net/mac80211/debugfs_key.c index 1243d1db5c59..4aa47d074a79 100644 --- a/trunk/net/mac80211/debugfs_key.c +++ b/trunk/net/mac80211/debugfs_key.c @@ -203,13 +203,9 @@ static ssize_t key_key_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { struct ieee80211_key *key = file->private_data; - int i, bufsize = 2 * key->conf.keylen + 2; + int i, res, bufsize = 2 * key->conf.keylen + 2; char *buf = kmalloc(bufsize, GFP_KERNEL); char *p = buf; - ssize_t res; - - if (!buf) - return -ENOMEM; for (i = 0; i < key->conf.keylen; i++) p += scnprintf(p, bufsize + buf - p, "%02x", key->conf.key[i]); diff --git a/trunk/net/mac80211/main.c b/trunk/net/mac80211/main.c index 107a0cbe52ac..6b322fa681f5 100644 --- a/trunk/net/mac80211/main.c +++ b/trunk/net/mac80211/main.c @@ -677,11 +677,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) /* * Calculate scan IE length -- we need this to alloc * memory and to subtract from the driver limit. It - * includes the DS Params, (extended) supported rates, and HT + * includes the (extended) supported rates and HT * information -- SSID is the driver's responsibility. */ - local->scan_ies_len = 4 + max_bitrates /* (ext) supp rates */ + - 3 /* DS Params */; + local->scan_ies_len = 4 + max_bitrates; /* (ext) supp rates */ if (supp_ht) local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap); diff --git a/trunk/net/netfilter/xt_socket.c b/trunk/net/netfilter/xt_socket.c index 00d6ae838303..d94a858dc52a 100644 --- a/trunk/net/netfilter/xt_socket.c +++ b/trunk/net/netfilter/xt_socket.c @@ -195,7 +195,7 @@ socket_mt4_v1(const struct sk_buff *skb, struct xt_action_param *par) static int extract_icmp6_fields(const struct sk_buff *skb, unsigned int outside_hdrlen, - int *protocol, + u8 *protocol, struct in6_addr **raddr, struct in6_addr **laddr, __be16 *rport, @@ -252,7 +252,8 @@ socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par) struct sock *sk; struct in6_addr *daddr, *saddr; __be16 dport, sport; - int thoff, tproto; + int thoff; + u8 tproto; const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo; tproto = ipv6_find_hdr(skb, &thoff, -1, NULL); @@ -304,7 +305,7 @@ socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par) sk = NULL; } - pr_debug("proto %hhd %pI6:%hu -> %pI6:%hu " + pr_debug("proto %hhu %pI6:%hu -> %pI6:%hu " "(orig %pI6:%hu) sock %p\n", tproto, saddr, ntohs(sport), daddr, ntohs(dport), diff --git a/trunk/net/socket.c b/trunk/net/socket.c index 5247ae10f374..ee3cd280c76e 100644 --- a/trunk/net/socket.c +++ b/trunk/net/socket.c @@ -305,17 +305,19 @@ static const struct super_operations sockfs_ops = { .statfs = simple_statfs, }; -static struct dentry *sockfs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int sockfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, + struct vfsmount *mnt) { - return mount_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC); + return get_sb_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC, + mnt); } static struct vfsmount *sock_mnt __read_mostly; static struct file_system_type sock_fs_type = { .name = "sockfs", - .mount = sockfs_mount, + .get_sb = sockfs_get_sb, .kill_sb = kill_anon_super, }; diff --git a/trunk/net/sunrpc/rpc_pipe.c b/trunk/net/sunrpc/rpc_pipe.c index 10a17a37ec4e..7df92d237cb8 100644 --- a/trunk/net/sunrpc/rpc_pipe.c +++ b/trunk/net/sunrpc/rpc_pipe.c @@ -28,7 +28,7 @@ #include #include -static struct vfsmount *rpc_mnt __read_mostly; +static struct vfsmount *rpc_mount __read_mostly; static int rpc_mount_count; static struct file_system_type rpc_pipe_fs_type; @@ -417,16 +417,16 @@ struct vfsmount *rpc_get_mount(void) { int err; - err = simple_pin_fs(&rpc_pipe_fs_type, &rpc_mnt, &rpc_mount_count); + err = simple_pin_fs(&rpc_pipe_fs_type, &rpc_mount, &rpc_mount_count); if (err != 0) return ERR_PTR(err); - return rpc_mnt; + return rpc_mount; } EXPORT_SYMBOL_GPL(rpc_get_mount); void rpc_put_mount(void) { - simple_release_fs(&rpc_mnt, &rpc_mount_count); + simple_release_fs(&rpc_mount, &rpc_mount_count); } EXPORT_SYMBOL_GPL(rpc_put_mount); @@ -1018,17 +1018,17 @@ rpc_fill_super(struct super_block *sb, void *data, int silent) return 0; } -static struct dentry * -rpc_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int +rpc_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return mount_single(fs_type, flags, data, rpc_fill_super); + return get_sb_single(fs_type, flags, data, rpc_fill_super, mnt); } static struct file_system_type rpc_pipe_fs_type = { .owner = THIS_MODULE, .name = "rpc_pipefs", - .mount = rpc_mount, + .get_sb = rpc_get_sb, .kill_sb = kill_litter_super, }; diff --git a/trunk/samples/Kconfig b/trunk/samples/Kconfig index e03cf0e374d7..954a1d550c5f 100644 --- a/trunk/samples/Kconfig +++ b/trunk/samples/Kconfig @@ -54,11 +54,4 @@ config SAMPLE_KFIFO If in doubt, say "N" here. -config SAMPLE_KDB - tristate "Build kdb command exmaple -- loadable modules only" - depends on KGDB_KDB && m - help - Build an example of how to dynamically add the hello - command to the kdb shell. - endif # SAMPLES diff --git a/trunk/samples/Makefile b/trunk/samples/Makefile index f26c0959fd86..76b3c3455c29 100644 --- a/trunk/samples/Makefile +++ b/trunk/samples/Makefile @@ -1,4 +1,4 @@ # Makefile for Linux samples code obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \ - hw_breakpoint/ kfifo/ kdb/ + hw_breakpoint/ kfifo/ diff --git a/trunk/samples/kdb/Makefile b/trunk/samples/kdb/Makefile deleted file mode 100644 index fbedf39d9356..000000000000 --- a/trunk/samples/kdb/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_SAMPLE_KDB) += kdb_hello.o diff --git a/trunk/samples/kdb/kdb_hello.c b/trunk/samples/kdb/kdb_hello.c deleted file mode 100644 index c1c2fa0f62c2..000000000000 --- a/trunk/samples/kdb/kdb_hello.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Created by: Jason Wessel - * - * Copyright (c) 2010 Wind River Systems, Inc. All Rights Reserved. - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include - -/* - * All kdb shell command call backs receive argc and argv, where - * argv[0] is the command the end user typed - */ -static int kdb_hello_cmd(int argc, const char **argv) -{ - if (argc > 1) - return KDB_ARGCOUNT; - - if (argc) - kdb_printf("Hello %s.\n", argv[1]); - else - kdb_printf("Hello world!\n"); - - return 0; -} - - -static int __init kdb_hello_cmd_init(void) -{ - /* - * Registration of a dynamically added kdb command is done with - * kdb_register() with the arguments being: - * 1: The name of the shell command - * 2: The function that processes the command - * 3: Description of the usage of any arguments - * 4: Descriptive text when you run help - * 5: Number of characters to complete the command - * 0 == type the whole command - * 1 == match both "g" and "go" for example - */ - kdb_register("hello", kdb_hello_cmd, "[string]", - "Say Hello World or Hello [string]", 0); - return 0; -} - -static void __exit kdb_hello_cmd_exit(void) -{ - kdb_unregister("hello"); -} - -module_init(kdb_hello_cmd_init); -module_exit(kdb_hello_cmd_exit); - -MODULE_AUTHOR("WindRiver"); -MODULE_DESCRIPTION("KDB example to add a hello command"); -MODULE_LICENSE("GPL"); diff --git a/trunk/scripts/kconfig/streamline_config.pl b/trunk/scripts/kconfig/streamline_config.pl index c70a27d924f0..cc10bcfda64f 100644 --- a/trunk/scripts/kconfig/streamline_config.pl +++ b/trunk/scripts/kconfig/streamline_config.pl @@ -137,7 +137,17 @@ sub read_kconfig { my $config; my @kconfigs; - open(KIN, "$ksource/$kconfig") || die "Can't open $kconfig"; + my $source = "$ksource/$kconfig"; + my $last_source = ""; + + # Check for any environment variables used + while ($source =~ /\$(\w+)/ && $last_source ne $source) { + my $env = $1; + $last_source = $source; + $source =~ s/\$$env/$ENV{$env}/; + } + + open(KIN, "$source") || die "Can't open $kconfig"; while () { chomp; diff --git a/trunk/scripts/recordmcount.c b/trunk/scripts/recordmcount.c index f2f32eee2c5b..26e1271259ba 100644 --- a/trunk/scripts/recordmcount.c +++ b/trunk/scripts/recordmcount.c @@ -217,39 +217,6 @@ is_mcounted_section_name(char const *const txtname) #define RECORD_MCOUNT_64 #include "recordmcount.h" -/* 64-bit EM_MIPS has weird ELF64_Rela.r_info. - * http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf - * We interpret Table 29 Relocation Operation (Elf64_Rel, Elf64_Rela) [p.40] - * to imply the order of the members; the spec does not say so. - * typedef unsigned char Elf64_Byte; - * fails on MIPS64 because their already has it! - */ - -typedef uint8_t myElf64_Byte; /* Type for a 8-bit quantity. */ - -union mips_r_info { - Elf64_Xword r_info; - struct { - Elf64_Word r_sym; /* Symbol index. */ - myElf64_Byte r_ssym; /* Special symbol. */ - myElf64_Byte r_type3; /* Third relocation. */ - myElf64_Byte r_type2; /* Second relocation. */ - myElf64_Byte r_type; /* First relocation. */ - } r_mips; -}; - -static uint64_t MIPS64_r_sym(Elf64_Rel const *rp) -{ - return w(((union mips_r_info){ .r_info = rp->r_info }).r_mips.r_sym); -} - -static void MIPS64_r_info(Elf64_Rel *const rp, unsigned sym, unsigned type) -{ - rp->r_info = ((union mips_r_info){ - .r_mips = { .r_sym = w(sym), .r_type = type } - }).r_info; -} - static void do_file(char const *const fname) { @@ -301,7 +268,6 @@ do_file(char const *const fname) case EM_386: reltype = R_386_32; break; case EM_ARM: reltype = R_ARM_ABS32; break; case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break; - case EM_MIPS: /* reltype: e_class */ gpfx = '_'; break; case EM_PPC: reltype = R_PPC_ADDR32; gpfx = '_'; break; case EM_PPC64: reltype = R_PPC64_ADDR64; gpfx = '_'; break; case EM_S390: /* reltype: e_class */ gpfx = '_'; break; @@ -325,10 +291,6 @@ do_file(char const *const fname) } if (EM_S390 == w2(ehdr->e_machine)) reltype = R_390_32; - if (EM_MIPS == w2(ehdr->e_machine)) { - reltype = R_MIPS_32; - is_fake_mcount32 = MIPS32_is_fake_mcount; - } do32(ehdr, fname, reltype); } break; case ELFCLASS64: { @@ -341,12 +303,6 @@ do_file(char const *const fname) } if (EM_S390 == w2(ghdr->e_machine)) reltype = R_390_64; - if (EM_MIPS == w2(ghdr->e_machine)) { - reltype = R_MIPS_64; - Elf64_r_sym = MIPS64_r_sym; - Elf64_r_info = MIPS64_r_info; - is_fake_mcount64 = MIPS64_is_fake_mcount; - } do64(ghdr, fname, reltype); } break; } /* end switch */ diff --git a/trunk/scripts/recordmcount.h b/trunk/scripts/recordmcount.h index 58e933a20544..7f39d0943d2d 100644 --- a/trunk/scripts/recordmcount.h +++ b/trunk/scripts/recordmcount.h @@ -19,28 +19,20 @@ * Licensed under the GNU General Public License, version 2 (GPLv2). */ #undef append_func -#undef is_fake_mcount -#undef fn_is_fake_mcount -#undef MIPS_is_fake_mcount #undef sift_rel_mcount #undef find_secsym_ndx #undef __has_rel_mcount #undef has_rel_mcount #undef tot_relsize #undef do_func -#undef Elf_Addr #undef Elf_Ehdr #undef Elf_Shdr #undef Elf_Rel #undef Elf_Rela #undef Elf_Sym #undef ELF_R_SYM -#undef Elf_r_sym #undef ELF_R_INFO -#undef Elf_r_info #undef ELF_ST_BIND -#undef fn_ELF_R_SYM -#undef fn_ELF_R_INFO #undef uint_t #undef _w #undef _align @@ -54,22 +46,14 @@ # define has_rel_mcount has64_rel_mcount # define tot_relsize tot64_relsize # define do_func do64 -# define is_fake_mcount is_fake_mcount64 -# define fn_is_fake_mcount fn_is_fake_mcount64 -# define MIPS_is_fake_mcount MIPS64_is_fake_mcount -# define Elf_Addr Elf64_Addr # define Elf_Ehdr Elf64_Ehdr # define Elf_Shdr Elf64_Shdr # define Elf_Rel Elf64_Rel # define Elf_Rela Elf64_Rela # define Elf_Sym Elf64_Sym # define ELF_R_SYM ELF64_R_SYM -# define Elf_r_sym Elf64_r_sym # define ELF_R_INFO ELF64_R_INFO -# define Elf_r_info Elf64_r_info # define ELF_ST_BIND ELF64_ST_BIND -# define fn_ELF_R_SYM fn_ELF64_R_SYM -# define fn_ELF_R_INFO fn_ELF64_R_INFO # define uint_t uint64_t # define _w w8 # define _align 7u @@ -82,81 +66,20 @@ # define has_rel_mcount has32_rel_mcount # define tot_relsize tot32_relsize # define do_func do32 -# define is_fake_mcount is_fake_mcount32 -# define fn_is_fake_mcount fn_is_fake_mcount32 -# define MIPS_is_fake_mcount MIPS32_is_fake_mcount -# define Elf_Addr Elf32_Addr # define Elf_Ehdr Elf32_Ehdr # define Elf_Shdr Elf32_Shdr # define Elf_Rel Elf32_Rel # define Elf_Rela Elf32_Rela # define Elf_Sym Elf32_Sym # define ELF_R_SYM ELF32_R_SYM -# define Elf_r_sym Elf32_r_sym # define ELF_R_INFO ELF32_R_INFO -# define Elf_r_info Elf32_r_info # define ELF_ST_BIND ELF32_ST_BIND -# define fn_ELF_R_SYM fn_ELF32_R_SYM -# define fn_ELF_R_INFO fn_ELF32_R_INFO # define uint_t uint32_t # define _w w # define _align 3u # define _size 4 #endif -/* Functions and pointers that do_file() may override for specific e_machine. */ -static int fn_is_fake_mcount(Elf_Rel const *rp) -{ - return 0; -} -static int (*is_fake_mcount)(Elf_Rel const *rp) = fn_is_fake_mcount; - -static uint_t fn_ELF_R_SYM(Elf_Rel const *rp) -{ - return ELF_R_SYM(_w(rp->r_info)); -} -static uint_t (*Elf_r_sym)(Elf_Rel const *rp) = fn_ELF_R_SYM; - -static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type) -{ - rp->r_info = ELF_R_INFO(sym, type); -} -static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO; - -/* - * MIPS mcount long call has 2 _mcount symbols, only the position of the 1st - * _mcount symbol is needed for dynamic function tracer, with it, to disable - * tracing(ftrace_make_nop), the instruction in the position is replaced with - * the "b label" instruction, to enable tracing(ftrace_make_call), replace the - * instruction back. So, here, we set the 2nd one as fake and filter it. - * - * c: 3c030000 lui v1,0x0 <--> b label - * c: R_MIPS_HI16 _mcount - * c: R_MIPS_NONE *ABS* - * c: R_MIPS_NONE *ABS* - * 10: 64630000 daddiu v1,v1,0 - * 10: R_MIPS_LO16 _mcount - * 10: R_MIPS_NONE *ABS* - * 10: R_MIPS_NONE *ABS* - * 14: 03e0082d move at,ra - * 18: 0060f809 jalr v1 - * label: - */ -#define MIPS_FAKEMCOUNT_OFFSET 4 - -static int MIPS_is_fake_mcount(Elf_Rel const *rp) -{ - static Elf_Addr old_r_offset; - Elf_Addr current_r_offset = _w(rp->r_offset); - int is_fake; - - is_fake = old_r_offset && - (current_r_offset - old_r_offset == MIPS_FAKEMCOUNT_OFFSET); - old_r_offset = current_r_offset; - - return is_fake; -} - /* Append the new shstrtab, Elf_Shdr[], __mcount_loc and its relocations. */ static void append_func(Elf_Ehdr *const ehdr, Elf_Shdr *const shstr, @@ -234,6 +157,7 @@ static void append_func(Elf_Ehdr *const ehdr, uwrite(fd_map, ehdr, sizeof(*ehdr)); } + /* * Look at the relocations in order to find the calls to mcount. * Accumulate the section offsets that are found, and their relocation info, @@ -273,22 +197,22 @@ static uint_t *sift_rel_mcount(uint_t *mlocp, for (t = nrel; t; --t) { if (!mcountsym) { Elf_Sym const *const symp = - &sym0[Elf_r_sym(relp)]; + &sym0[ELF_R_SYM(_w(relp->r_info))]; char const *symname = &str0[w(symp->st_name)]; if ('.' == symname[0]) ++symname; /* ppc64 hack */ if (0 == strcmp((('_' == gpfx) ? "_mcount" : "mcount"), symname)) - mcountsym = Elf_r_sym(relp); + mcountsym = ELF_R_SYM(_w(relp->r_info)); } - if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) { + if (mcountsym == ELF_R_SYM(_w(relp->r_info))) { uint_t const addend = _w(_w(relp->r_offset) - recval); mrelp->r_offset = _w(offbase + ((void *)mlocp - (void *)mloc0)); - Elf_r_info(mrelp, recsym, reltype); + mrelp->r_info = _w(ELF_R_INFO(recsym, reltype)); if (sizeof(Elf_Rela) == rel_entsize) { ((Elf_Rela *)mrelp)->r_addend = addend; *mlocp++ = 0; diff --git a/trunk/security/inode.c b/trunk/security/inode.c index c4df2fbebe6b..cb8f47c66a58 100644 --- a/trunk/security/inode.c +++ b/trunk/security/inode.c @@ -131,17 +131,17 @@ static int fill_super(struct super_block *sb, void *data, int silent) return simple_fill_super(sb, SECURITYFS_MAGIC, files); } -static struct dentry *get_sb(struct file_system_type *fs_type, +static int get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, - void *data) + void *data, struct vfsmount *mnt) { - return mount_single(fs_type, flags, data, fill_super); + return get_sb_single(fs_type, flags, data, fill_super, mnt); } static struct file_system_type fs_type = { .owner = THIS_MODULE, .name = "securityfs", - .mount = get_sb, + .get_sb = get_sb, .kill_sb = kill_litter_super, }; diff --git a/trunk/security/selinux/selinuxfs.c b/trunk/security/selinux/selinuxfs.c index 073fd5b0a53a..55a755c1a1bd 100644 --- a/trunk/security/selinux/selinuxfs.c +++ b/trunk/security/selinux/selinuxfs.c @@ -1909,15 +1909,16 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) goto out; } -static struct dentry *sel_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int sel_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, + struct vfsmount *mnt) { - return mount_single(fs_type, flags, data, sel_fill_super); + return get_sb_single(fs_type, flags, data, sel_fill_super, mnt); } static struct file_system_type sel_fs_type = { .name = "selinuxfs", - .mount = sel_mount, + .get_sb = sel_get_sb, .kill_sb = kill_litter_super, }; diff --git a/trunk/security/smack/smackfs.c b/trunk/security/smack/smackfs.c index dc1fd6239f24..7512502d0162 100644 --- a/trunk/security/smack/smackfs.c +++ b/trunk/security/smack/smackfs.c @@ -1310,25 +1310,27 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) } /** - * smk_mount - get the smackfs superblock + * smk_get_sb - get the smackfs superblock * @fs_type: passed along without comment * @flags: passed along without comment * @dev_name: passed along without comment * @data: passed along without comment + * @mnt: passed along without comment * * Just passes everything along. * * Returns what the lower level code does. */ -static struct dentry *smk_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int smk_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, + struct vfsmount *mnt) { - return mount_single(fs_type, flags, data, smk_fill_super); + return get_sb_single(fs_type, flags, data, smk_fill_super, mnt); } static struct file_system_type smk_fs_type = { .name = "smackfs", - .mount = smk_mount, + .get_sb = smk_get_sb, .kill_sb = kill_litter_super, };